提交 ca20cf32 编写于 作者: B Blue Swirl

Compile loader only once

Callers must pass ELF machine, byte swapping and symbol LSB clearing
information to ELF loader. A.out loader needs page size information, pass
that too as a parameter.

Extract prototypes to a separate file. Move loader.[ch] and elf_ops.h under hw.

Adjust callers. Also use target_phys_addr_t instead of target_ulong for
addresses: loader addresses aren't virtual.
Signed-off-by: NBlue Swirl <blauwirbel@gmail.com>
上级 a333cd71
......@@ -11,6 +11,7 @@ VPATH=$(SRC_PATH):$(SRC_PATH)/hw
QEMU_CFLAGS+=-I.. -I$(SRC_PATH)/fpu
obj-y =
obj-y += loader.o
obj-y += virtio.o
obj-y += fw_cfg.o
obj-y += watchdog.o
......
......@@ -155,7 +155,7 @@ endif
# System emulator target
ifdef CONFIG_SOFTMMU
obj-y = vl.o monitor.o pci.o loader.o isa_mmio.o machine.o \
obj-y = vl.o monitor.o pci.o isa_mmio.o machine.o \
gdbstub.o gdbstub-xml.o msix.o ioport.o
# virtio has to be here due to weird dependency between PCI and virtio-net.
# need to fix this properly
......
......@@ -3,6 +3,7 @@
#include "qemu-common.h"
#ifdef NEED_CPU_H
/* Disassemble this for me please... (debugging). */
void disas(FILE *out, void *code, unsigned long size);
void target_disas(FILE *out, target_ulong code, target_ulong size, int flags);
......@@ -15,12 +16,13 @@ void monitor_disas(Monitor *mon, CPUState *env,
/* Look up symbol for debugging purpose. Returns "" if unknown. */
const char *lookup_symbol(target_ulong orig_addr);
#endif
struct syminfo;
struct elf32_sym;
struct elf64_sym;
typedef const char *(*lookup_symbol_t)(struct syminfo *s, target_ulong orig_addr);
typedef const char *(*lookup_symbol_t)(struct syminfo *s, target_phys_addr_t orig_addr);
struct syminfo {
lookup_symbol_t lookup_symbol;
......
......@@ -11,6 +11,8 @@
#include "mcf.h"
#include "sysemu.h"
#include "boards.h"
#include "loader.h"
#include "elf.h"
#define KERNEL_LOAD_ADDR 0x10000
#define AN5206_MBAR_ADDR 0x10000000
......@@ -35,7 +37,7 @@ static void an5206_init(ram_addr_t ram_size,
CPUState *env;
int kernel_size;
uint64_t elf_entry;
target_ulong entry;
target_phys_addr_t entry;
if (!cpu_model)
cpu_model = "m5206";
......@@ -66,7 +68,8 @@ static void an5206_init(ram_addr_t ram_size,
exit(1);
}
kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL);
kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL,
1, ELF_MACHINE, 0);
entry = elf_entry;
if (kernel_size < 0) {
kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL);
......
......@@ -10,6 +10,8 @@
#include "hw.h"
#include "arm-misc.h"
#include "sysemu.h"
#include "loader.h"
#include "elf.h"
#define KERNEL_ARGS_ADDR 0x100
#define KERNEL_LOAD_ADDR 0x00010000
......@@ -191,7 +193,8 @@ void arm_load_kernel(CPUState *env, struct arm_boot_info *info)
int n;
int is_linux = 0;
uint64_t elf_entry;
target_ulong entry;
target_phys_addr_t entry;
int big_endian;
/* Load the kernel. */
if (!info->kernel_filename) {
......@@ -206,8 +209,15 @@ void arm_load_kernel(CPUState *env, struct arm_boot_info *info)
qemu_register_reset(main_cpu_reset, env);
}
#ifdef TARGET_WORDS_BIGENDIAN
big_endian = 1;
#else
big_endian = 0;
#endif
/* Assume that raw images are linux kernels, and ELF images are not. */
kernel_size = load_elf(info->kernel_filename, 0, &elf_entry, NULL, NULL);
kernel_size = load_elf(info->kernel_filename, 0, &elf_entry, NULL, NULL,
big_endian, ELF_MACHINE, 1);
entry = elf_entry;
if (kernel_size < 0) {
kernel_size = load_uimage(info->kernel_filename, &entry, NULL,
......
......@@ -10,6 +10,8 @@
#include "sysbus.h"
#include "arm-misc.h"
#include "sysemu.h"
#include "loader.h"
#include "elf.h"
/* Bitbanded IO. Each word corresponds to a single bit. */
......@@ -166,6 +168,7 @@ qemu_irq *armv7m_init(int flash_size, int sram_size,
uint64_t entry;
uint64_t lowaddr;
int i;
int big_endian;
flash_size *= 1024;
sram_size *= 1024;
......@@ -206,7 +209,14 @@ qemu_irq *armv7m_init(int flash_size, int sram_size,
pic[i] = qdev_get_gpio_in(nvic, i);
}
image_size = load_elf(kernel_filename, 0, &entry, &lowaddr, NULL);
#ifdef TARGET_WORDS_BIGENDIAN
big_endian = 1;
#else
big_endian = 0;
#endif
image_size = load_elf(kernel_filename, 0, &entry, &lowaddr, NULL,
big_endian, ELF_MACHINE, 1);
if (image_size < 0) {
image_size = load_image_targphys(kernel_filename, 0, flash_size);
lowaddr = 0;
......
......@@ -28,6 +28,8 @@
#include "boards.h"
#include "sysemu.h"
#include "etraxfs.h"
#include "loader.h"
#include "elf.h"
#define D(x)
#define DNAND(x)
......@@ -344,7 +346,7 @@ void axisdev88_init (ram_addr_t ram_size,
/* Boots a kernel elf binary, os/linux-2.6/vmlinux from the axis
devboard SDK. */
kernel_size = load_elf(kernel_filename, -0x80000000LL,
&entry, NULL, &high);
&entry, NULL, &high, 0, ELF_MACHINE, 0);
bootstrap_pc = entry;
if (kernel_size < 0) {
/* Takes a kimage from the axis devboard SDK. */
......
......@@ -9,6 +9,8 @@
#include "hw.h"
#include "sysemu.h"
#include "boards.h"
#include "loader.h"
#include "elf.h"
#define KERNEL_LOAD_ADDR 0x10000
......@@ -22,7 +24,7 @@ static void dummy_m68k_init(ram_addr_t ram_size,
CPUState *env;
int kernel_size;
uint64_t elf_entry;
target_ulong entry;
target_phys_addr_t entry;
if (!cpu_model)
cpu_model = "cfv4e";
......@@ -41,7 +43,8 @@ static void dummy_m68k_init(ram_addr_t ram_size,
/* Load kernel. */
if (kernel_filename) {
kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL);
kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL,
1, ELF_MACHINE, 0);
entry = elf_entry;
if (kernel_size < 0) {
kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL);
......
......@@ -73,7 +73,8 @@ static int glue(symfind, SZ)(const void *s0, const void *s1)
return result;
}
static const char *glue(lookup_symbol, SZ)(struct syminfo *s, target_ulong orig_addr)
static const char *glue(lookup_symbol, SZ)(struct syminfo *s,
target_phys_addr_t orig_addr)
{
struct elf_sym *syms = glue(s->disas_symtab.elf, SZ);
struct elf_sym key;
......@@ -98,7 +99,8 @@ static int glue(symcmp, SZ)(const void *s0, const void *s1)
: ((sym0->st_value > sym1->st_value) ? 1 : 0);
}
static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab)
static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab,
int clear_lsb)
{
struct elf_shdr *symtab, *strtab, *shdr_table = NULL;
struct elf_sym *syms = NULL;
......@@ -141,10 +143,10 @@ static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab)
}
continue;
}
#if defined(TARGET_ARM) || defined (TARGET_MIPS)
/* The bottom address bit marks a Thumb or MIPS16 symbol. */
syms[i].st_value &= ~(target_ulong)1;
#endif
if (clear_lsb) {
/* The bottom address bit marks a Thumb or MIPS16 symbol. */
syms[i].st_value &= ~(glue(glue(Elf, SZ), _Addr))1;
}
i++;
}
syms = qemu_realloc(syms, nsyms * sizeof(*syms));
......@@ -179,7 +181,8 @@ static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab)
static int glue(load_elf, SZ)(int fd, int64_t address_offset,
int must_swab, uint64_t *pentry,
uint64_t *lowaddr, uint64_t *highaddr)
uint64_t *lowaddr, uint64_t *highaddr,
int elf_machine, int clear_lsb)
{
struct elfhdr ehdr;
struct elf_phdr *phdr = NULL, *ph;
......@@ -194,7 +197,7 @@ static int glue(load_elf, SZ)(int fd, int64_t address_offset,
glue(bswap_ehdr, SZ)(&ehdr);
}
switch (ELF_MACHINE) {
switch (elf_machine) {
case EM_PPC64:
if (EM_PPC64 != ehdr.e_machine)
if (EM_PPC != ehdr.e_machine)
......@@ -206,14 +209,14 @@ static int glue(load_elf, SZ)(int fd, int64_t address_offset,
goto fail;
break;
default:
if (ELF_MACHINE != ehdr.e_machine)
if (elf_machine != ehdr.e_machine)
goto fail;
}
if (pentry)
*pentry = (uint64_t)(elf_sword)ehdr.e_entry;
glue(load_symbols, SZ)(&ehdr, fd, must_swab);
glue(load_symbols, SZ)(&ehdr, fd, must_swab, clear_lsb);
size = ehdr.e_phnum * sizeof(phdr[0]);
lseek(fd, ehdr.e_phoff, SEEK_SET);
......
......@@ -28,6 +28,8 @@
#include "net.h"
#include "flash.h"
#include "etraxfs.h"
#include "loader.h"
#include "elf.h"
#define FLASH_SIZE 0x2000000
#define INTMEM_SIZE (128 * 1024)
......@@ -136,7 +138,7 @@ void bareetraxfs_init (ram_addr_t ram_size,
/* Boots a kernel elf binary, os/linux-2.6/vmlinux from the axis
devboard SDK. */
kernel_size = load_elf(kernel_filename, -0x80000000LL,
&entry, NULL, &high);
&entry, NULL, &high, 0, ELF_MACHINE, 0);
bootstrap_pc = entry;
if (kernel_size < 0) {
/* Takes a kimage from the axis devboard SDK. */
......
......@@ -42,10 +42,11 @@
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu-common.h"
#include "hw.h"
#include "disas.h"
#include "sysemu.h"
#include "uboot_image.h"
#include "loader.h"
#include <zlib.h>
......@@ -172,7 +173,6 @@ struct exec
uint32_t a_drsize; /* length of relocation info for data, in bytes */
};
#ifdef BSWAP_NEEDED
static void bswap_ahdr(struct exec *e)
{
bswap32s(&e->a_info);
......@@ -184,9 +184,6 @@ static void bswap_ahdr(struct exec *e)
bswap32s(&e->a_trsize);
bswap32s(&e->a_drsize);
}
#else
#define bswap_ahdr(x) do { } while (0)
#endif
#define N_MAGIC(exec) ((exec).a_info & 0xffff)
#define OMAGIC 0407
......@@ -197,17 +194,18 @@ static void bswap_ahdr(struct exec *e)
#define N_TXTOFF(x) \
(N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) : \
(N_MAGIC(x) == QMAGIC ? 0 : sizeof (struct exec)))
#define N_TXTADDR(x) (N_MAGIC(x) == QMAGIC ? TARGET_PAGE_SIZE : 0)
#define _N_SEGMENT_ROUND(x) (((x) + TARGET_PAGE_SIZE - 1) & ~(TARGET_PAGE_SIZE - 1))
#define N_TXTADDR(x, target_page_size) (N_MAGIC(x) == QMAGIC ? target_page_size : 0)
#define _N_SEGMENT_ROUND(x, target_page_size) (((x) + target_page_size - 1) & ~(target_page_size - 1))
#define _N_TXTENDADDR(x) (N_TXTADDR(x)+(x).a_text)
#define _N_TXTENDADDR(x, target_page_size) (N_TXTADDR(x, target_page_size)+(x).a_text)
#define N_DATADDR(x) \
(N_MAGIC(x)==OMAGIC? (_N_TXTENDADDR(x)) \
: (_N_SEGMENT_ROUND (_N_TXTENDADDR(x))))
#define N_DATADDR(x, target_page_size) \
(N_MAGIC(x)==OMAGIC? (_N_TXTENDADDR(x, target_page_size)) \
: (_N_SEGMENT_ROUND (_N_TXTENDADDR(x, target_page_size), target_page_size)))
int load_aout(const char *filename, target_phys_addr_t addr, int max_sz)
int load_aout(const char *filename, target_phys_addr_t addr, int max_sz,
int bswap_needed, target_phys_addr_t target_page_size)
{
int fd, size, ret;
struct exec e;
......@@ -221,7 +219,9 @@ int load_aout(const char *filename, target_phys_addr_t addr, int max_sz)
if (size < 0)
goto fail;
bswap_ahdr(&e);
if (bswap_needed) {
bswap_ahdr(&e);
}
magic = N_MAGIC(e);
switch (magic) {
......@@ -236,13 +236,14 @@ int load_aout(const char *filename, target_phys_addr_t addr, int max_sz)
goto fail;
break;
case NMAGIC:
if (N_DATADDR(e) + e.a_data > max_sz)
if (N_DATADDR(e, target_page_size) + e.a_data > max_sz)
goto fail;
lseek(fd, N_TXTOFF(e), SEEK_SET);
size = read_targphys(fd, addr, e.a_text);
if (size < 0)
goto fail;
ret = read_targphys(fd, addr + N_DATADDR(e), e.a_data);
ret = read_targphys(fd, addr + N_DATADDR(e, target_page_size),
e.a_data);
if (ret < 0)
goto fail;
size += ret;
......@@ -307,9 +308,10 @@ static void *load_at(int fd, int offset, int size)
/* return < 0 if error, otherwise the number of bytes loaded in memory */
int load_elf(const char *filename, int64_t address_offset,
uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr)
uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr,
int big_endian, int elf_machine, int clear_lsb)
{
int fd, data_order, host_data_order, must_swab, ret;
int fd, data_order, target_data_order, must_swab, ret;
uint8_t e_ident[EI_NIDENT];
fd = open(filename, O_RDONLY | O_BINARY);
......@@ -330,22 +332,22 @@ int load_elf(const char *filename, int64_t address_offset,
data_order = ELFDATA2LSB;
#endif
must_swab = data_order != e_ident[EI_DATA];
if (big_endian) {
target_data_order = ELFDATA2MSB;
} else {
target_data_order = ELFDATA2LSB;
}
#ifdef TARGET_WORDS_BIGENDIAN
host_data_order = ELFDATA2MSB;
#else
host_data_order = ELFDATA2LSB;
#endif
if (host_data_order != e_ident[EI_DATA])
if (target_data_order != e_ident[EI_DATA])
return -1;
lseek(fd, 0, SEEK_SET);
if (e_ident[EI_CLASS] == ELFCLASS64) {
ret = load_elf64(fd, address_offset, must_swab, pentry,
lowaddr, highaddr);
lowaddr, highaddr, elf_machine, clear_lsb);
} else {
ret = load_elf32(fd, address_offset, must_swab, pentry,
lowaddr, highaddr);
lowaddr, highaddr, elf_machine, clear_lsb);
}
close(fd);
......@@ -455,8 +457,8 @@ static ssize_t gunzip(void *dst, size_t dstlen, uint8_t *src,
}
/* Load a U-Boot image. */
int load_uimage(const char *filename, target_ulong *ep, target_ulong *loadaddr,
int *is_linux)
int load_uimage(const char *filename, target_phys_addr_t *ep,
target_phys_addr_t *loadaddr, int *is_linux)
{
int fd;
int size;
......
#ifndef LOADER_H
#define LOADER_H
/* loader.c */
int get_image_size(const char *filename);
int load_image(const char *filename, uint8_t *addr); /* deprecated */
int load_image_targphys(const char *filename, target_phys_addr_t, int max_sz);
int load_elf(const char *filename, int64_t address_offset,
uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr,
int big_endian, int elf_machine, int clear_lsb);
int load_aout(const char *filename, target_phys_addr_t addr, int max_sz,
int bswap_needed, target_phys_addr_t target_page_size);
int load_uimage(const char *filename, target_phys_addr_t *ep,
target_phys_addr_t *loadaddr, int *is_linux);
int fread_targphys(target_phys_addr_t dst_addr, size_t nbytes, FILE *f);
int fread_targphys_ok(target_phys_addr_t dst_addr, size_t nbytes, FILE *f);
int read_targphys(int fd, target_phys_addr_t dst_addr, size_t nbytes);
void pstrcpy_targphys(target_phys_addr_t dest, int buf_size,
const char *source);
#endif
......@@ -11,6 +11,8 @@
#include "sysemu.h"
#include "net.h"
#include "boards.h"
#include "loader.h"
#include "elf.h"
#define SYS_FREQ 66000000
......@@ -201,7 +203,7 @@ static void mcf5208evb_init(ram_addr_t ram_size,
CPUState *env;
int kernel_size;
uint64_t elf_entry;
target_ulong entry;
target_phys_addr_t entry;
qemu_irq *pic;
if (!cpu_model)
......@@ -268,7 +270,8 @@ static void mcf5208evb_init(ram_addr_t ram_size,
exit(1);
}
kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL);
kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL,
1, ELF_MACHINE, 0);
entry = elf_entry;
if (kernel_size < 0) {
kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL);
......
......@@ -33,6 +33,7 @@
#include "net.h"
#include "scsi.h"
#include "mips-bios.h"
#include "loader.h"
enum jazz_model_e
{
......
......@@ -39,6 +39,8 @@
#include "qemu-log.h"
#include "mips-bios.h"
#include "ide.h"
#include "loader.h"
#include "elf.h"
//#define DEBUG_BOARD_INIT
......@@ -687,10 +689,17 @@ static int64_t load_kernel (CPUState *env)
int index = 0;
long initrd_size;
ram_addr_t initrd_offset;
int big_endian;
#ifdef TARGET_WORDS_BIGENDIAN
big_endian = 1;
#else
big_endian = 0;
#endif
if (load_elf(loaderparams.kernel_filename, VIRT_TO_PHYS_ADDEND,
(uint64_t *)&kernel_entry, (uint64_t *)&kernel_low,
(uint64_t *)&kernel_high) < 0) {
(uint64_t *)&kernel_high, big_endian, ELF_MACHINE, 1) < 0) {
fprintf(stderr, "qemu: could not load kernel '%s'\n",
loaderparams.kernel_filename);
exit(1);
......
......@@ -32,6 +32,8 @@
#include "sysemu.h"
#include "boards.h"
#include "mips-bios.h"
#include "loader.h"
#include "elf.h"
#ifdef TARGET_MIPS64
#define PHYS_TO_VIRT(x) ((x) | ~0x7fffffffULL)
......@@ -54,10 +56,17 @@ static void load_kernel (CPUState *env)
long kernel_size;
long initrd_size;
ram_addr_t initrd_offset;
int big_endian;
#ifdef TARGET_WORDS_BIGENDIAN
big_endian = 1;
#else
big_endian = 0;
#endif
kernel_size = load_elf(loaderparams.kernel_filename, VIRT_TO_PHYS_ADDEND,
(uint64_t *)&entry, (uint64_t *)&kernel_low,
(uint64_t *)&kernel_high);
(uint64_t *)&kernel_high, big_endian, ELF_MACHINE, 1);
if (kernel_size >= 0) {
if ((entry & ~0x7fffffffULL) == 0x80000000)
entry = (int32_t)entry;
......
......@@ -18,6 +18,8 @@
#include "qemu-log.h"
#include "mips-bios.h"
#include "ide.h"
#include "loader.h"
#include "elf.h"
#define PHYS_TO_VIRT(x) ((x) | ~(target_ulong)0x7fffffff)
......@@ -77,10 +79,16 @@ static void load_kernel (CPUState *env)
long kernel_size, initrd_size;
ram_addr_t initrd_offset;
int ret;
int big_endian;
#ifdef TARGET_WORDS_BIGENDIAN
big_endian = 1;
#else
big_endian = 0;
#endif
kernel_size = load_elf(loaderparams.kernel_filename, VIRT_TO_PHYS_ADDEND,
(uint64_t *)&entry, (uint64_t *)&kernel_low,
(uint64_t *)&kernel_high);
(uint64_t *)&kernel_high, big_endian, ELF_MACHINE, 1);
if (kernel_size >= 0) {
if ((entry & ~0x7fffffffULL) == 0x80000000)
entry = (int32_t)entry;
......
......@@ -30,6 +30,7 @@
#include "flash.h"
#include "hw.h"
#include "bt.h"
#include "loader.h"
/* Nokia N8x0 support */
struct n800_s {
......
......@@ -24,6 +24,7 @@
#include "boards.h"
#include "arm-misc.h"
#include "devices.h"
#include "loader.h"
static uint32_t static_readb(void *opaque, target_phys_addr_t offset)
{
......
......@@ -37,6 +37,8 @@
#include "watchdog.h"
#include "smbios.h"
#include "ide.h"
#include "loader.h"
#include "elf.h"
/* output Bochs bios info messages */
//#define DEBUG_BIOS
......@@ -657,7 +659,8 @@ static int load_multiboot(void *fw_cfg,
uint64_t elf_entry;
int kernel_size;
fclose(f);
kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL);
kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL,
0, ELF_MACHINE, 0);
if (kernel_size < 0) {
fprintf(stderr, "Error while loading elf kernel\n");
exit(1);
......
......@@ -32,6 +32,8 @@
#include "boards.h"
#include "device_tree.h"
#include "xilinx.h"
#include "loader.h"
#include "elf.h"
#define LMB_BRAM_SIZE (128 * 1024)
#define FLASH_SIZE (16 * 1024 * 1024)
......@@ -155,11 +157,13 @@ petalogix_s3adsp1800_init(ram_addr_t ram_size,
/* Boots a kernel elf binary. */
kernel_size = load_elf(kernel_filename, 0,
&entry, &low, &high);
&entry, &low, &high,
1, ELF_MACHINE, 0);
base32 = entry;
if (base32 == 0xc0000000) {
kernel_size = load_elf(kernel_filename, -0x30000000LL,
&entry, NULL, NULL);
&entry, NULL, NULL,
1, ELF_MACHINE, 0);
}
/* Always boot into physical ram. */
bootstrap_pc = ddr_base + (entry & 0x0fffffff);
......
......@@ -27,6 +27,7 @@
#include "sysemu.h"
#include "nvram.h"
#include "qemu-log.h"
#include "loader.h"
//#define PPC_DEBUG_IRQ
//#define PPC_DEBUG_TB
......
......@@ -30,6 +30,7 @@
#include "block.h"
#include "boards.h"
#include "qemu-log.h"
#include "loader.h"
#define BIOS_FILENAME "ppc405_rom.bin"
#define BIOS_SIZE (2048 * 1024)
......
......@@ -22,6 +22,8 @@
#include "kvm.h"
#include "kvm_ppc.h"
#include "device_tree.h"
#include "loader.h"
#include "elf.h"
#define BINARY_DEVICE_TREE_FILE "bamboo.dtb"
......@@ -93,8 +95,8 @@ static void bamboo_init(ram_addr_t ram_size,
CPUState *env;
uint64_t elf_entry;
uint64_t elf_lowaddr;
target_ulong entry = 0;
target_ulong loadaddr = 0;
target_phys_addr_t entry = 0;
target_phys_addr_t loadaddr = 0;
target_long kernel_size = 0;
target_ulong initrd_base = 0;
target_long initrd_size = 0;
......@@ -126,7 +128,7 @@ static void bamboo_init(ram_addr_t ram_size,
kernel_size = load_uimage(kernel_filename, &entry, &loadaddr, NULL);
if (kernel_size < 0) {
kernel_size = load_elf(kernel_filename, 0, &elf_entry, &elf_lowaddr,
NULL);
NULL, 1, ELF_MACHINE, 0);
entry = elf_entry;
loadaddr = elf_lowaddr;
}
......
......@@ -36,6 +36,8 @@
#include "escc.h"
#include "openpic.h"
#include "ide.h"
#include "loader.h"
#include "elf.h"
#define MAX_IDE_BUS 2
#define VGA_BIOS_SIZE 65536
......@@ -145,7 +147,8 @@ static void ppc_core99_init (ram_addr_t ram_size,
/* Load OpenBIOS (ELF) */
if (filename) {
bios_size = load_elf(filename, 0, NULL, NULL, NULL);
bios_size = load_elf(filename, 0, NULL, NULL, NULL, 1, ELF_MACHINE, 0);
qemu_free(filename);
} else {
bios_size = -1;
......@@ -187,19 +190,28 @@ static void ppc_core99_init (ram_addr_t ram_size,
if (linux_boot) {
uint64_t lowaddr = 0;
int bswap_needed;
#ifdef BSWAP_NEEDED
bswap_needed = 1;
#else
bswap_needed = 0;
#endif
kernel_base = KERNEL_LOAD_ADDR;
/* Now we can load the kernel. The first step tries to load the kernel
supposing PhysAddr = 0x00000000. If that was wrong the kernel is
loaded again, the new PhysAddr being computed from lowaddr. */
kernel_size = load_elf(kernel_filename, kernel_base, NULL, &lowaddr, NULL);
kernel_size = load_elf(kernel_filename, kernel_base, NULL, &lowaddr, NULL,
1, ELF_MACHINE, 0);
if (kernel_size > 0 && lowaddr != KERNEL_LOAD_ADDR) {
kernel_size = load_elf(kernel_filename, (2 * kernel_base) - lowaddr,
NULL, NULL, NULL);
NULL, NULL, NULL, 1, ELF_MACHINE, 0);
}
if (kernel_size < 0)
kernel_size = load_aout(kernel_filename, kernel_base,
ram_size - kernel_base);
ram_size - kernel_base, bswap_needed,
TARGET_PAGE_SIZE);
if (kernel_size < 0)
kernel_size = load_image_targphys(kernel_filename,
kernel_base,
......
......@@ -36,6 +36,8 @@
#include "fw_cfg.h"
#include "escc.h"
#include "ide.h"
#include "loader.h"
#include "elf.h"
#define MAX_IDE_BUS 2
#define VGA_BIOS_SIZE 65536
......@@ -180,7 +182,8 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
/* Load OpenBIOS (ELF) */
if (filename) {
bios_size = load_elf(filename, 0, NULL, NULL, NULL);
bios_size = load_elf(filename, 0, NULL, NULL, NULL,
1, ELF_MACHINE, 0);
qemu_free(filename);
} else {
bios_size = -1;
......@@ -222,18 +225,27 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
if (linux_boot) {
uint64_t lowaddr = 0;
int bswap_needed;
#ifdef BSWAP_NEEDED
bswap_needed = 1;
#else
bswap_needed = 0;
#endif
kernel_base = KERNEL_LOAD_ADDR;
/* Now we can load the kernel. The first step tries to load the kernel
supposing PhysAddr = 0x00000000. If that was wrong the kernel is
loaded again, the new PhysAddr being computed from lowaddr. */
kernel_size = load_elf(kernel_filename, kernel_base, NULL, &lowaddr, NULL);
kernel_size = load_elf(kernel_filename, kernel_base, NULL, &lowaddr, NULL,
1, ELF_MACHINE, 0);
if (kernel_size > 0 && lowaddr != KERNEL_LOAD_ADDR) {
kernel_size = load_elf(kernel_filename, (2 * kernel_base) - lowaddr,
NULL, NULL, NULL);
NULL, NULL, NULL, 1, ELF_MACHINE, 0);
}
if (kernel_size < 0)
kernel_size = load_aout(kernel_filename, kernel_base,
ram_size - kernel_base);
ram_size - kernel_base, bswap_needed,
TARGET_PAGE_SIZE);
if (kernel_size < 0)
kernel_size = load_image_targphys(kernel_filename,
kernel_base,
......
......@@ -33,6 +33,7 @@
#include "boards.h"
#include "qemu-log.h"
#include "ide.h"
#include "loader.h"
//#define HARD_DEBUG_PPC_IO
//#define DEBUG_PPC_IO
......
......@@ -29,6 +29,8 @@
#include "device_tree.h"
#include "openpic.h"
#include "ppce500.h"
#include "loader.h"
#include "elf.h"
#define BINARY_DEVICE_TREE_FILE "mpc8544ds.dtb"
#define UIMAGE_LOAD_BASE 0
......@@ -160,8 +162,8 @@ static void mpc8544ds_init(ram_addr_t ram_size,
CPUState *env;
uint64_t elf_entry;
uint64_t elf_lowaddr;
target_ulong entry=0;
target_ulong loadaddr=UIMAGE_LOAD_BASE;
target_phys_addr_t entry=0;
target_phys_addr_t loadaddr=UIMAGE_LOAD_BASE;
target_long kernel_size=0;
target_ulong dt_base=DTB_LOAD_BASE;
target_ulong initrd_base=INITRD_LOAD_BASE;
......@@ -226,7 +228,7 @@ static void mpc8544ds_init(ram_addr_t ram_size,
kernel_size = load_uimage(kernel_filename, &entry, &loadaddr, NULL);
if (kernel_size < 0) {
kernel_size = load_elf(kernel_filename, 0, &elf_entry, &elf_lowaddr,
NULL);
NULL, 1, ELF_MACHINE, 0);
entry = elf_entry;
loadaddr = elf_lowaddr;
}
......
......@@ -32,6 +32,7 @@
#include "net.h"
#include "sh7750_regs.h"
#include "ide.h"
#include "loader.h"
#define SDRAM_BASE 0x0c000000 /* Physical location of SDRAM: Area 3 */
#define SDRAM_SIZE 0x04000000
......
......@@ -32,6 +32,7 @@
#include "sh.h"
#include "sysemu.h"
#include "boards.h"
#include "loader.h"
#define BIOS_FILENAME "shix_bios.bin"
#define BIOS_ADDRESS 0xA0000000
......
......@@ -13,6 +13,7 @@
#include "sysemu.h"
#include "smbios.h"
#include "loader.h"
/*
* Structures shared with the BIOS
......
......@@ -37,6 +37,8 @@
#include "fw_cfg.h"
#include "escc.h"
#include "qdev-addr.h"
#include "loader.h"
#include "elf.h"
//#define DEBUG_IRQ
......@@ -302,11 +304,19 @@ static unsigned long sun4m_load_kernel(const char *kernel_filename,
kernel_size = 0;
if (linux_boot) {
int bswap_needed;
#ifdef BSWAP_NEEDED
bswap_needed = 1;
#else
bswap_needed = 0;
#endif
kernel_size = load_elf(kernel_filename, -0xf0000000ULL, NULL, NULL,
NULL);
NULL, 1, ELF_MACHINE, 0);
if (kernel_size < 0)
kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR,
RAM_size - KERNEL_LOAD_ADDR);
RAM_size - KERNEL_LOAD_ADDR, bswap_needed,
TARGET_PAGE_SIZE);
if (kernel_size < 0)
kernel_size = load_image_targphys(kernel_filename,
KERNEL_LOAD_ADDR,
......@@ -608,7 +618,8 @@ static void prom_init(target_phys_addr_t addr, const char *bios_name)
}
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
if (filename) {
ret = load_elf(filename, addr - PROM_VADDR, NULL, NULL, NULL);
ret = load_elf(filename, addr - PROM_VADDR, NULL, NULL, NULL,
1, ELF_MACHINE, 0);
if (ret < 0 || ret > PROM_SIZE_MAX) {
ret = load_image_targphys(filename, addr, PROM_SIZE_MAX);
}
......
......@@ -34,6 +34,8 @@
#include "fw_cfg.h"
#include "sysbus.h"
#include "ide.h"
#include "loader.h"
#include "elf.h"
//#define DEBUG_IRQ
......@@ -164,10 +166,19 @@ static unsigned long sun4u_load_kernel(const char *kernel_filename,
kernel_size = 0;
if (linux_boot) {
kernel_size = load_elf(kernel_filename, 0, NULL, NULL, NULL);
int bswap_needed;
#ifdef BSWAP_NEEDED
bswap_needed = 1;
#else
bswap_needed = 0;
#endif
kernel_size = load_elf(kernel_filename, 0, NULL, NULL, NULL,
1, ELF_MACHINE, 0);
if (kernel_size < 0)
kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR,
RAM_size - KERNEL_LOAD_ADDR);
RAM_size - KERNEL_LOAD_ADDR, bswap_needed,
TARGET_PAGE_SIZE);
if (kernel_size < 0)
kernel_size = load_image_targphys(kernel_filename,
KERNEL_LOAD_ADDR,
......@@ -418,7 +429,8 @@ static void prom_init(target_phys_addr_t addr, const char *bios_name)
}
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
if (filename) {
ret = load_elf(filename, addr - PROM_VADDR, NULL, NULL, NULL);
ret = load_elf(filename, addr - PROM_VADDR, NULL, NULL, NULL,
1, ELF_MACHINE, 0);
if (ret < 0 || ret > PROM_SIZE_MAX) {
ret = load_image_targphys(filename, addr, PROM_SIZE_MAX);
}
......
#include "hw.h"
#include "sh.h"
#include "sysemu.h"
#include "loader.h"
#define CE1 0x0100
#define CE2 0x0200
......
......@@ -1315,10 +1315,10 @@ static void load_symbols(struct elfhdr *hdr, int fd)
s->disas_num_syms = nsyms;
#if ELF_CLASS == ELFCLASS32
s->disas_symtab.elf32 = syms;
s->lookup_symbol = lookup_symbolxx;
s->lookup_symbol = (lookup_symbol_t)lookup_symbolxx;
#else
s->disas_symtab.elf64 = syms;
s->lookup_symbol = lookup_symbolxx;
s->lookup_symbol = (lookup_symbol_t)lookup_symbolxx;
#endif
s->next = syminfos;
syminfos = s;
......
......@@ -237,24 +237,6 @@ extern CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
#define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
#ifdef NEED_CPU_H
/* loader.c */
int get_image_size(const char *filename);
int load_image(const char *filename, uint8_t *addr); /* deprecated */
int load_image_targphys(const char *filename, target_phys_addr_t, int max_sz);
int load_elf(const char *filename, int64_t address_offset,
uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr);
int load_aout(const char *filename, target_phys_addr_t addr, int max_sz);
int load_uimage(const char *filename, target_ulong *ep, target_ulong *loadaddr,
int *is_linux);
int fread_targphys(target_phys_addr_t dst_addr, size_t nbytes, FILE *f);
int fread_targphys_ok(target_phys_addr_t dst_addr, size_t nbytes, FILE *f);
int read_targphys(int fd, target_phys_addr_t dst_addr, size_t nbytes);
void pstrcpy_targphys(target_phys_addr_t dest, int buf_size,
const char *source);
#endif
#ifdef HAS_AUDIO
struct soundhw {
const char *name;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册