⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 32bitbios_support.c

📁 xen虚拟机源代码安装包
💻 C
字号:
/* * 32bitbios_support.c - relocation of 32bit BIOS implementation * * Stefan Berger, stefanb@us.ibm.com * Copyright (c) 2006, International Business Machines Corporation. * * Keir Fraser, keir@xensource.com * 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, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR 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., 59 Temple * Place - Suite 330, Boston, MA 02111-1307 USA. */#include <inttypes.h>#include <elf.h>#ifdef __sun__#include <sys/machelf.h>#endif#include "util.h"#include "config.h"#include "../rombios/32bit/32bitbios_flat.h"static void relocate_32bitbios(char *elfarray, uint32_t elfarraysize){    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;    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");        if ( shdr[i].sh_type != SHT_REL )            continue;        syms = (Elf32_Sym *)shdr[shdr[i].sh_link].sh_addr;        rels = (Elf32_Rel *)shdr[i].sh_addr;        code = (char      *)shdr[shdr[i].sh_info].sh_addr;        for ( j = 0; j < shdr[i].sh_size / sizeof(Elf32_Rel); j++ )        {            sym = &syms[ELF32_R_SYM(rels[j].r_info)];            loc = (uint32_t *)&code[rels[j].r_offset];            fix = shdr[sym->st_shndx].sh_addr + sym->st_value;            switch ( ELF32_R_TYPE(rels[j].r_info) )            {            case R_386_PC32:                *loc += fix - (uint32_t)loc;                break;            case R_386_32:                *loc += fix;                break;            }        }    }    /* 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);    printf("done\n");}void highbios_setup(void){    relocate_32bitbios((char *)highbios_array, sizeof(highbios_array));}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -