[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] hvmloader: Fix ROMBIOS highmem relocation. Only SHF_ALLOC sections
# HG changeset patch # User Keir Fraser <keir@xxxxxxxxxxxxx> # Date 1177013189 -3600 # Node ID c7c67a1a70777b934cba17d01b7437558ef4f336 # Parent 56fa8b1f8e08b5186ad8110881f779cb13a34190 hvmloader: Fix ROMBIOS highmem relocation. Only SHF_ALLOC sections should be relocated. SHT_NOBITS must be handled properly (space explicitly allocated and zeroed). Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- tools/firmware/rombios/32bit/jumptable.h | 11 - tools/firmware/hvmloader/32bitbios_support.c | 157 +++++++++++++++------------ tools/firmware/hvmloader/util.c | 13 +- tools/firmware/hvmloader/util.h | 3 tools/firmware/rombios/32bit/32bitbios.c | 3 5 files changed, 102 insertions(+), 85 deletions(-) diff -r 56fa8b1f8e08 -r c7c67a1a7077 tools/firmware/hvmloader/32bitbios_support.c --- a/tools/firmware/hvmloader/32bitbios_support.c Thu Apr 19 19:32:10 2007 +0100 +++ b/tools/firmware/hvmloader/32bitbios_support.c Thu Apr 19 21:06:29 2007 +0100 @@ -3,6 +3,9 @@ * * Stefan Berger, stefanb@xxxxxxxxxx * Copyright (c) 2006, International Business Machines Corporation. + * + * Keir Fraser, keir@xxxxxxxxxxxxx + * Copyright (c) 2007, XenSource Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -28,24 +31,94 @@ #include "config.h" #include "../rombios/32bit/32bitbios_flat.h" -#include "../rombios/32bit/jumptable.h" -/* Relocate ELF file of type ET_REL */ -static void relocate_elf(char *elfarray) +static void relocate_32bitbios(char *elfarray, uint32_t elfarraysize) { Elf32_Ehdr *ehdr = (Elf32_Ehdr *)elfarray; Elf32_Shdr *shdr = (Elf32_Shdr *)&elfarray[ehdr->e_shoff]; - Elf32_Sym *syms, *sym; - Elf32_Rel *rels; - char *code; - uint32_t *loc, fix; - int i, j; + char *secstrings = &elfarray[shdr[ehdr->e_shstrndx].sh_offset]; + char *jump_table; + uint32_t reloc_off, reloc_size; + char *highbiosarea; + int i, jump_sec_idx = 0; + /* + * Step 1. General elf cleanup, and compute total relocation size. + */ + reloc_off = 0; for ( i = 0; i < ehdr->e_shnum; i++ ) + { + /* By default all section data points into elf image data array. */ shdr[i].sh_addr = (Elf32_Addr)&elfarray[shdr[i].sh_offset]; + if ( !strcmp(".biosjumptable", secstrings + shdr[i].sh_name) ) + { + /* We do not relocate the BIOS jump table to high memory. */ + shdr[i].sh_flags &= ~SHF_ALLOC; + jump_sec_idx = i; + } + + /* Fix up a corner case of address alignment. */ + if ( shdr[i].sh_addralign == 0 ) + shdr[i].sh_addralign = 1; + + /* Any section which contains run-time data must be relocated. */ + if ( shdr[i].sh_flags & SHF_ALLOC ) + { + uint32_t mask = shdr[i].sh_addralign - 1; + reloc_off = (reloc_off + mask) & ~mask; + reloc_off += shdr[i].sh_size; + } + } + + /* + * Step 2. Now we know the relocation size, allocate a chunk of high mem. + */ + reloc_size = reloc_off; + printf("%d bytes of ROMBIOS high-memory extensions:\n", reloc_size); + highbiosarea = (char *)(long)e820_malloc(reloc_size); + BUG_ON(highbiosarea == NULL); + printf(" Relocating to 0x%x-0x%x ... ", + (uint32_t)&highbiosarea[0], + (uint32_t)&highbiosarea[reloc_size]); + + /* + * Step 3. Copy run-time data into the newly-allocated high-memory chunk. + */ + reloc_off = 0; for ( i = 0; i < ehdr->e_shnum; i++ ) { + uint32_t mask = shdr[i].sh_addralign - 1; + + /* Nothing to do for non-run-time sections. */ + if ( !(shdr[i].sh_flags & SHF_ALLOC) ) + continue; + + /* Copy from old location. */ + reloc_off = (reloc_off + mask) & ~mask; + if ( shdr[i].sh_type == SHT_NOBITS ) + memset(&highbiosarea[reloc_off], 0, shdr[i].sh_size); + else + memcpy(&highbiosarea[reloc_off], (void *)shdr[i].sh_addr, + shdr[i].sh_size); + + /* Update address to new location. */ + shdr[i].sh_addr = (Elf32_Addr)&highbiosarea[reloc_off]; + reloc_off += shdr[i].sh_size; + } + BUG_ON(reloc_off != reloc_size); + + /* + * Step 4. Perform relocations in high memory. + */ + for ( i = 0; i < ehdr->e_shnum; i++ ) + { + Elf32_Sym *syms, *sym; + Elf32_Rel *rels; + char *code; + uint32_t *loc, fix; + int j; + if ( shdr[i].sh_type == SHT_RELA ) printf("Unsupported section type SHT_RELA\n"); @@ -74,65 +147,19 @@ static void relocate_elf(char *elfarray) } } } -} -/* Scan the rombios for the destination of the jump table. */ -static char *get_jump_table_start(void) -{ - char *bios_mem; + /* Step 5. Find the ROMBIOS jump-table stub and copy in the real table. */ + for ( jump_table = (char *)ROMBIOS_BEGIN; + jump_table != (char *)ROMBIOS_END; + jump_table++ ) + if ( !strncmp(jump_table, "___JMPT", 7) ) + break; + BUG_ON(jump_table == NULL); + BUG_ON(jump_sec_idx == 0); + memcpy(jump_table, (char *)shdr[jump_sec_idx].sh_addr, + shdr[jump_sec_idx].sh_size); - for ( bios_mem = (char *)ROMBIOS_BEGIN; - bios_mem != (char *)ROMBIOS_END; - bios_mem++ ) - if ( !strncmp(bios_mem, "___JMPT", 7) ) - return bios_mem; - - return NULL; -} - -/* Copy relocated jumptable into the rombios. */ -static void copy_jumptable(char *elfarray) -{ - Elf32_Ehdr *ehdr = (Elf32_Ehdr *)elfarray; - Elf32_Shdr *shdr = (Elf32_Shdr *)&elfarray[ehdr->e_shoff]; - char *secstrings = &elfarray[shdr[ehdr->e_shstrndx].sh_offset]; - char *jump_table = get_jump_table_start(); - int i; - - /* Find the section with the jump table and copy to lower BIOS memory. */ - for ( i = 0; i < ehdr->e_shnum; i++ ) - if ( !strcmp(JUMPTABLE_SECTION_NAME, secstrings + shdr[i].sh_name) ) - break; - - if ( i == ehdr->e_shnum ) - { - printf("Could not find " JUMPTABLE_SECTION_NAME " section in file.\n"); - return; - } - - if ( jump_table == NULL ) - { - printf("Could not find jump table in file.\n"); - return; - } - - memcpy(jump_table, (char *)shdr[i].sh_addr, shdr[i].sh_size); -} - -static void relocate_32bitbios(char *elfarray, uint32_t elfarraysize) -{ - char *highbiosarea; - - highbiosarea = (char *)(long)e820_malloc(elfarraysize); - if ( highbiosarea == NULL ) - { - printf("No available memory for BIOS high memory area\n"); - return; - } - - memcpy(highbiosarea, elfarray, elfarraysize); - relocate_elf(highbiosarea); - copy_jumptable(highbiosarea); + printf("done\n"); } void highbios_setup(void) diff -r 56fa8b1f8e08 -r c7c67a1a7077 tools/firmware/hvmloader/util.c --- a/tools/firmware/hvmloader/util.c Thu Apr 19 19:32:10 2007 +0100 +++ b/tools/firmware/hvmloader/util.c Thu Apr 19 21:06:29 2007 +0100 @@ -335,12 +335,13 @@ uint32_t e820_malloc(uint32_t size) ent[i].addr = addr; ent[i].size = size; ent[i].type = E820_RESERVED; - break; - } - - e820_collapse(); - - return addr; + + e820_collapse(); + + return addr; + } + + return 0; } uint32_t ioapic_read(uint32_t reg) diff -r 56fa8b1f8e08 -r c7c67a1a7077 tools/firmware/hvmloader/util.h --- a/tools/firmware/hvmloader/util.h Thu Apr 19 19:32:10 2007 +0100 +++ b/tools/firmware/hvmloader/util.h Thu Apr 19 21:06:29 2007 +0100 @@ -14,7 +14,8 @@ extern void __assert_failed(char *assert #define ASSERT(p) \ do { if (!(p)) __assert_failed(#p, __FILE__, __LINE__); } while (0) extern void __bug(char *file, int line) __attribute__((noreturn)); -#define BUG() __bug() +#define BUG() __bug(__FILE__, __LINE__) +#define BUG_ON(p) do { if (p) BUG(); } while (0) /* I/O output */ void outb(uint16_t addr, uint8_t val); diff -r 56fa8b1f8e08 -r c7c67a1a7077 tools/firmware/rombios/32bit/32bitbios.c --- a/tools/firmware/rombios/32bit/32bitbios.c Thu Apr 19 19:32:10 2007 +0100 +++ b/tools/firmware/rombios/32bit/32bitbios.c Thu Apr 19 21:06:29 2007 +0100 @@ -20,7 +20,6 @@ * Author: Stefan Berger <stefanb@xxxxxxxxxx> */ #include "rombios_compat.h" -#include "jumptable.h" #include "32bitprotos.h" /* @@ -29,7 +28,7 @@ here. */ #define TABLE_ENTRY(idx, func) [idx] = (uint32_t)func -uint32_t jumptable[IDX_LAST+1] __attribute__((section (JUMPTABLE_SECTION_NAME))) = +uint32_t jumptable[IDX_LAST+1] __attribute__((section (".biosjumptable"))) = { TABLE_ENTRY(IDX_TCPA_ACPI_INIT, tcpa_acpi_init), TABLE_ENTRY(IDX_TCPA_EXTEND_ACPI_LOG, tcpa_extend_acpi_log), diff -r 56fa8b1f8e08 -r c7c67a1a7077 tools/firmware/rombios/32bit/jumptable.h --- a/tools/firmware/rombios/32bit/jumptable.h Thu Apr 19 19:32:10 2007 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,11 +0,0 @@ -#ifndef JUMPTABLE_H -#define JUMPTABLE_H - -/* - name of the section the 32bit BIOS must have and where the array of - function poiners is built; hvmloader looks for this section and copies - it into the lower BIOS in the 0xf000 segment - */ -#define JUMPTABLE_SECTION_NAME ".biosjumptable" - -#endif _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |