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: Blue Swirl <blauwirbel@gmail.com>
This commit is contained in:
parent
a333cd7166
commit
ca20cf32ab
@ -11,6 +11,7 @@ VPATH=$(SRC_PATH):$(SRC_PATH)/hw
|
|||||||
QEMU_CFLAGS+=-I.. -I$(SRC_PATH)/fpu
|
QEMU_CFLAGS+=-I.. -I$(SRC_PATH)/fpu
|
||||||
|
|
||||||
obj-y =
|
obj-y =
|
||||||
|
obj-y += loader.o
|
||||||
obj-y += virtio.o
|
obj-y += virtio.o
|
||||||
obj-y += fw_cfg.o
|
obj-y += fw_cfg.o
|
||||||
obj-y += watchdog.o
|
obj-y += watchdog.o
|
||||||
|
@ -155,7 +155,7 @@ endif
|
|||||||
# System emulator target
|
# System emulator target
|
||||||
ifdef CONFIG_SOFTMMU
|
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
|
gdbstub.o gdbstub-xml.o msix.o ioport.o
|
||||||
# virtio has to be here due to weird dependency between PCI and virtio-net.
|
# virtio has to be here due to weird dependency between PCI and virtio-net.
|
||||||
# need to fix this properly
|
# need to fix this properly
|
||||||
|
4
disas.h
4
disas.h
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
|
|
||||||
|
#ifdef NEED_CPU_H
|
||||||
/* Disassemble this for me please... (debugging). */
|
/* Disassemble this for me please... (debugging). */
|
||||||
void disas(FILE *out, void *code, unsigned long size);
|
void disas(FILE *out, void *code, unsigned long size);
|
||||||
void target_disas(FILE *out, target_ulong code, target_ulong size, int flags);
|
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. */
|
/* Look up symbol for debugging purpose. Returns "" if unknown. */
|
||||||
const char *lookup_symbol(target_ulong orig_addr);
|
const char *lookup_symbol(target_ulong orig_addr);
|
||||||
|
#endif
|
||||||
|
|
||||||
struct syminfo;
|
struct syminfo;
|
||||||
struct elf32_sym;
|
struct elf32_sym;
|
||||||
struct elf64_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 {
|
struct syminfo {
|
||||||
lookup_symbol_t lookup_symbol;
|
lookup_symbol_t lookup_symbol;
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
#include "mcf.h"
|
#include "mcf.h"
|
||||||
#include "sysemu.h"
|
#include "sysemu.h"
|
||||||
#include "boards.h"
|
#include "boards.h"
|
||||||
|
#include "loader.h"
|
||||||
|
#include "elf.h"
|
||||||
|
|
||||||
#define KERNEL_LOAD_ADDR 0x10000
|
#define KERNEL_LOAD_ADDR 0x10000
|
||||||
#define AN5206_MBAR_ADDR 0x10000000
|
#define AN5206_MBAR_ADDR 0x10000000
|
||||||
@ -35,7 +37,7 @@ static void an5206_init(ram_addr_t ram_size,
|
|||||||
CPUState *env;
|
CPUState *env;
|
||||||
int kernel_size;
|
int kernel_size;
|
||||||
uint64_t elf_entry;
|
uint64_t elf_entry;
|
||||||
target_ulong entry;
|
target_phys_addr_t entry;
|
||||||
|
|
||||||
if (!cpu_model)
|
if (!cpu_model)
|
||||||
cpu_model = "m5206";
|
cpu_model = "m5206";
|
||||||
@ -66,7 +68,8 @@ static void an5206_init(ram_addr_t ram_size,
|
|||||||
exit(1);
|
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;
|
entry = elf_entry;
|
||||||
if (kernel_size < 0) {
|
if (kernel_size < 0) {
|
||||||
kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL);
|
kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL);
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
#include "hw.h"
|
#include "hw.h"
|
||||||
#include "arm-misc.h"
|
#include "arm-misc.h"
|
||||||
#include "sysemu.h"
|
#include "sysemu.h"
|
||||||
|
#include "loader.h"
|
||||||
|
#include "elf.h"
|
||||||
|
|
||||||
#define KERNEL_ARGS_ADDR 0x100
|
#define KERNEL_ARGS_ADDR 0x100
|
||||||
#define KERNEL_LOAD_ADDR 0x00010000
|
#define KERNEL_LOAD_ADDR 0x00010000
|
||||||
@ -191,7 +193,8 @@ void arm_load_kernel(CPUState *env, struct arm_boot_info *info)
|
|||||||
int n;
|
int n;
|
||||||
int is_linux = 0;
|
int is_linux = 0;
|
||||||
uint64_t elf_entry;
|
uint64_t elf_entry;
|
||||||
target_ulong entry;
|
target_phys_addr_t entry;
|
||||||
|
int big_endian;
|
||||||
|
|
||||||
/* Load the kernel. */
|
/* Load the kernel. */
|
||||||
if (!info->kernel_filename) {
|
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);
|
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. */
|
/* 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;
|
entry = elf_entry;
|
||||||
if (kernel_size < 0) {
|
if (kernel_size < 0) {
|
||||||
kernel_size = load_uimage(info->kernel_filename, &entry, NULL,
|
kernel_size = load_uimage(info->kernel_filename, &entry, NULL,
|
||||||
|
12
hw/armv7m.c
12
hw/armv7m.c
@ -10,6 +10,8 @@
|
|||||||
#include "sysbus.h"
|
#include "sysbus.h"
|
||||||
#include "arm-misc.h"
|
#include "arm-misc.h"
|
||||||
#include "sysemu.h"
|
#include "sysemu.h"
|
||||||
|
#include "loader.h"
|
||||||
|
#include "elf.h"
|
||||||
|
|
||||||
/* Bitbanded IO. Each word corresponds to a single bit. */
|
/* 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 entry;
|
||||||
uint64_t lowaddr;
|
uint64_t lowaddr;
|
||||||
int i;
|
int i;
|
||||||
|
int big_endian;
|
||||||
|
|
||||||
flash_size *= 1024;
|
flash_size *= 1024;
|
||||||
sram_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);
|
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) {
|
if (image_size < 0) {
|
||||||
image_size = load_image_targphys(kernel_filename, 0, flash_size);
|
image_size = load_image_targphys(kernel_filename, 0, flash_size);
|
||||||
lowaddr = 0;
|
lowaddr = 0;
|
||||||
|
@ -28,6 +28,8 @@
|
|||||||
#include "boards.h"
|
#include "boards.h"
|
||||||
#include "sysemu.h"
|
#include "sysemu.h"
|
||||||
#include "etraxfs.h"
|
#include "etraxfs.h"
|
||||||
|
#include "loader.h"
|
||||||
|
#include "elf.h"
|
||||||
|
|
||||||
#define D(x)
|
#define D(x)
|
||||||
#define DNAND(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
|
/* Boots a kernel elf binary, os/linux-2.6/vmlinux from the axis
|
||||||
devboard SDK. */
|
devboard SDK. */
|
||||||
kernel_size = load_elf(kernel_filename, -0x80000000LL,
|
kernel_size = load_elf(kernel_filename, -0x80000000LL,
|
||||||
&entry, NULL, &high);
|
&entry, NULL, &high, 0, ELF_MACHINE, 0);
|
||||||
bootstrap_pc = entry;
|
bootstrap_pc = entry;
|
||||||
if (kernel_size < 0) {
|
if (kernel_size < 0) {
|
||||||
/* Takes a kimage from the axis devboard SDK. */
|
/* Takes a kimage from the axis devboard SDK. */
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
#include "hw.h"
|
#include "hw.h"
|
||||||
#include "sysemu.h"
|
#include "sysemu.h"
|
||||||
#include "boards.h"
|
#include "boards.h"
|
||||||
|
#include "loader.h"
|
||||||
|
#include "elf.h"
|
||||||
|
|
||||||
#define KERNEL_LOAD_ADDR 0x10000
|
#define KERNEL_LOAD_ADDR 0x10000
|
||||||
|
|
||||||
@ -22,7 +24,7 @@ static void dummy_m68k_init(ram_addr_t ram_size,
|
|||||||
CPUState *env;
|
CPUState *env;
|
||||||
int kernel_size;
|
int kernel_size;
|
||||||
uint64_t elf_entry;
|
uint64_t elf_entry;
|
||||||
target_ulong entry;
|
target_phys_addr_t entry;
|
||||||
|
|
||||||
if (!cpu_model)
|
if (!cpu_model)
|
||||||
cpu_model = "cfv4e";
|
cpu_model = "cfv4e";
|
||||||
@ -41,7 +43,8 @@ static void dummy_m68k_init(ram_addr_t ram_size,
|
|||||||
|
|
||||||
/* Load kernel. */
|
/* Load kernel. */
|
||||||
if (kernel_filename) {
|
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;
|
entry = elf_entry;
|
||||||
if (kernel_size < 0) {
|
if (kernel_size < 0) {
|
||||||
kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL);
|
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;
|
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 *syms = glue(s->disas_symtab.elf, SZ);
|
||||||
struct elf_sym key;
|
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);
|
: ((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_shdr *symtab, *strtab, *shdr_table = NULL;
|
||||||
struct elf_sym *syms = 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;
|
continue;
|
||||||
}
|
}
|
||||||
#if defined(TARGET_ARM) || defined (TARGET_MIPS)
|
if (clear_lsb) {
|
||||||
/* The bottom address bit marks a Thumb or MIPS16 symbol. */
|
/* The bottom address bit marks a Thumb or MIPS16 symbol. */
|
||||||
syms[i].st_value &= ~(target_ulong)1;
|
syms[i].st_value &= ~(glue(glue(Elf, SZ), _Addr))1;
|
||||||
#endif
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
syms = qemu_realloc(syms, nsyms * sizeof(*syms));
|
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,
|
static int glue(load_elf, SZ)(int fd, int64_t address_offset,
|
||||||
int must_swab, uint64_t *pentry,
|
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 elfhdr ehdr;
|
||||||
struct elf_phdr *phdr = NULL, *ph;
|
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);
|
glue(bswap_ehdr, SZ)(&ehdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (ELF_MACHINE) {
|
switch (elf_machine) {
|
||||||
case EM_PPC64:
|
case EM_PPC64:
|
||||||
if (EM_PPC64 != ehdr.e_machine)
|
if (EM_PPC64 != ehdr.e_machine)
|
||||||
if (EM_PPC != 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;
|
goto fail;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (ELF_MACHINE != ehdr.e_machine)
|
if (elf_machine != ehdr.e_machine)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pentry)
|
if (pentry)
|
||||||
*pentry = (uint64_t)(elf_sword)ehdr.e_entry;
|
*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]);
|
size = ehdr.e_phnum * sizeof(phdr[0]);
|
||||||
lseek(fd, ehdr.e_phoff, SEEK_SET);
|
lseek(fd, ehdr.e_phoff, SEEK_SET);
|
@ -28,6 +28,8 @@
|
|||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "flash.h"
|
#include "flash.h"
|
||||||
#include "etraxfs.h"
|
#include "etraxfs.h"
|
||||||
|
#include "loader.h"
|
||||||
|
#include "elf.h"
|
||||||
|
|
||||||
#define FLASH_SIZE 0x2000000
|
#define FLASH_SIZE 0x2000000
|
||||||
#define INTMEM_SIZE (128 * 1024)
|
#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
|
/* Boots a kernel elf binary, os/linux-2.6/vmlinux from the axis
|
||||||
devboard SDK. */
|
devboard SDK. */
|
||||||
kernel_size = load_elf(kernel_filename, -0x80000000LL,
|
kernel_size = load_elf(kernel_filename, -0x80000000LL,
|
||||||
&entry, NULL, &high);
|
&entry, NULL, &high, 0, ELF_MACHINE, 0);
|
||||||
bootstrap_pc = entry;
|
bootstrap_pc = entry;
|
||||||
if (kernel_size < 0) {
|
if (kernel_size < 0) {
|
||||||
/* Takes a kimage from the axis devboard SDK. */
|
/* Takes a kimage from the axis devboard SDK. */
|
||||||
|
@ -42,10 +42,11 @@
|
|||||||
* with this program; if not, see <http://www.gnu.org/licenses/>.
|
* with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu-common.h"
|
#include "hw.h"
|
||||||
#include "disas.h"
|
#include "disas.h"
|
||||||
#include "sysemu.h"
|
#include "sysemu.h"
|
||||||
#include "uboot_image.h"
|
#include "uboot_image.h"
|
||||||
|
#include "loader.h"
|
||||||
|
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
|
||||||
@ -172,7 +173,6 @@ struct exec
|
|||||||
uint32_t a_drsize; /* length of relocation info for data, in bytes */
|
uint32_t a_drsize; /* length of relocation info for data, in bytes */
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef BSWAP_NEEDED
|
|
||||||
static void bswap_ahdr(struct exec *e)
|
static void bswap_ahdr(struct exec *e)
|
||||||
{
|
{
|
||||||
bswap32s(&e->a_info);
|
bswap32s(&e->a_info);
|
||||||
@ -184,9 +184,6 @@ static void bswap_ahdr(struct exec *e)
|
|||||||
bswap32s(&e->a_trsize);
|
bswap32s(&e->a_trsize);
|
||||||
bswap32s(&e->a_drsize);
|
bswap32s(&e->a_drsize);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
#define bswap_ahdr(x) do { } while (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define N_MAGIC(exec) ((exec).a_info & 0xffff)
|
#define N_MAGIC(exec) ((exec).a_info & 0xffff)
|
||||||
#define OMAGIC 0407
|
#define OMAGIC 0407
|
||||||
@ -197,17 +194,18 @@ static void bswap_ahdr(struct exec *e)
|
|||||||
#define N_TXTOFF(x) \
|
#define N_TXTOFF(x) \
|
||||||
(N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) : \
|
(N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) : \
|
||||||
(N_MAGIC(x) == QMAGIC ? 0 : 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_TXTADDR(x, target_page_size) (N_MAGIC(x) == QMAGIC ? target_page_size : 0)
|
||||||
#define _N_SEGMENT_ROUND(x) (((x) + TARGET_PAGE_SIZE - 1) & ~(TARGET_PAGE_SIZE - 1))
|
#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) \
|
#define N_DATADDR(x, target_page_size) \
|
||||||
(N_MAGIC(x)==OMAGIC? (_N_TXTENDADDR(x)) \
|
(N_MAGIC(x)==OMAGIC? (_N_TXTENDADDR(x, target_page_size)) \
|
||||||
: (_N_SEGMENT_ROUND (_N_TXTENDADDR(x))))
|
: (_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;
|
int fd, size, ret;
|
||||||
struct exec e;
|
struct exec e;
|
||||||
@ -221,7 +219,9 @@ int load_aout(const char *filename, target_phys_addr_t addr, int max_sz)
|
|||||||
if (size < 0)
|
if (size < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
if (bswap_needed) {
|
||||||
bswap_ahdr(&e);
|
bswap_ahdr(&e);
|
||||||
|
}
|
||||||
|
|
||||||
magic = N_MAGIC(e);
|
magic = N_MAGIC(e);
|
||||||
switch (magic) {
|
switch (magic) {
|
||||||
@ -236,13 +236,14 @@ int load_aout(const char *filename, target_phys_addr_t addr, int max_sz)
|
|||||||
goto fail;
|
goto fail;
|
||||||
break;
|
break;
|
||||||
case NMAGIC:
|
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;
|
goto fail;
|
||||||
lseek(fd, N_TXTOFF(e), SEEK_SET);
|
lseek(fd, N_TXTOFF(e), SEEK_SET);
|
||||||
size = read_targphys(fd, addr, e.a_text);
|
size = read_targphys(fd, addr, e.a_text);
|
||||||
if (size < 0)
|
if (size < 0)
|
||||||
goto fail;
|
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)
|
if (ret < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
size += ret;
|
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 */
|
/* return < 0 if error, otherwise the number of bytes loaded in memory */
|
||||||
int load_elf(const char *filename, int64_t address_offset,
|
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];
|
uint8_t e_ident[EI_NIDENT];
|
||||||
|
|
||||||
fd = open(filename, O_RDONLY | O_BINARY);
|
fd = open(filename, O_RDONLY | O_BINARY);
|
||||||
@ -330,22 +332,22 @@ int load_elf(const char *filename, int64_t address_offset,
|
|||||||
data_order = ELFDATA2LSB;
|
data_order = ELFDATA2LSB;
|
||||||
#endif
|
#endif
|
||||||
must_swab = data_order != e_ident[EI_DATA];
|
must_swab = data_order != e_ident[EI_DATA];
|
||||||
|
if (big_endian) {
|
||||||
|
target_data_order = ELFDATA2MSB;
|
||||||
|
} else {
|
||||||
|
target_data_order = ELFDATA2LSB;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef TARGET_WORDS_BIGENDIAN
|
if (target_data_order != e_ident[EI_DATA])
|
||||||
host_data_order = ELFDATA2MSB;
|
|
||||||
#else
|
|
||||||
host_data_order = ELFDATA2LSB;
|
|
||||||
#endif
|
|
||||||
if (host_data_order != e_ident[EI_DATA])
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
lseek(fd, 0, SEEK_SET);
|
lseek(fd, 0, SEEK_SET);
|
||||||
if (e_ident[EI_CLASS] == ELFCLASS64) {
|
if (e_ident[EI_CLASS] == ELFCLASS64) {
|
||||||
ret = load_elf64(fd, address_offset, must_swab, pentry,
|
ret = load_elf64(fd, address_offset, must_swab, pentry,
|
||||||
lowaddr, highaddr);
|
lowaddr, highaddr, elf_machine, clear_lsb);
|
||||||
} else {
|
} else {
|
||||||
ret = load_elf32(fd, address_offset, must_swab, pentry,
|
ret = load_elf32(fd, address_offset, must_swab, pentry,
|
||||||
lowaddr, highaddr);
|
lowaddr, highaddr, elf_machine, clear_lsb);
|
||||||
}
|
}
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
@ -455,8 +457,8 @@ static ssize_t gunzip(void *dst, size_t dstlen, uint8_t *src,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Load a U-Boot image. */
|
/* Load a U-Boot image. */
|
||||||
int load_uimage(const char *filename, target_ulong *ep, target_ulong *loadaddr,
|
int load_uimage(const char *filename, target_phys_addr_t *ep,
|
||||||
int *is_linux)
|
target_phys_addr_t *loadaddr, int *is_linux)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
int size;
|
int size;
|
21
hw/loader.h
Normal file
21
hw/loader.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#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 "sysemu.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "boards.h"
|
#include "boards.h"
|
||||||
|
#include "loader.h"
|
||||||
|
#include "elf.h"
|
||||||
|
|
||||||
#define SYS_FREQ 66000000
|
#define SYS_FREQ 66000000
|
||||||
|
|
||||||
@ -201,7 +203,7 @@ static void mcf5208evb_init(ram_addr_t ram_size,
|
|||||||
CPUState *env;
|
CPUState *env;
|
||||||
int kernel_size;
|
int kernel_size;
|
||||||
uint64_t elf_entry;
|
uint64_t elf_entry;
|
||||||
target_ulong entry;
|
target_phys_addr_t entry;
|
||||||
qemu_irq *pic;
|
qemu_irq *pic;
|
||||||
|
|
||||||
if (!cpu_model)
|
if (!cpu_model)
|
||||||
@ -268,7 +270,8 @@ static void mcf5208evb_init(ram_addr_t ram_size,
|
|||||||
exit(1);
|
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;
|
entry = elf_entry;
|
||||||
if (kernel_size < 0) {
|
if (kernel_size < 0) {
|
||||||
kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL);
|
kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL);
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "scsi.h"
|
#include "scsi.h"
|
||||||
#include "mips-bios.h"
|
#include "mips-bios.h"
|
||||||
|
#include "loader.h"
|
||||||
|
|
||||||
enum jazz_model_e
|
enum jazz_model_e
|
||||||
{
|
{
|
||||||
|
@ -39,6 +39,8 @@
|
|||||||
#include "qemu-log.h"
|
#include "qemu-log.h"
|
||||||
#include "mips-bios.h"
|
#include "mips-bios.h"
|
||||||
#include "ide.h"
|
#include "ide.h"
|
||||||
|
#include "loader.h"
|
||||||
|
#include "elf.h"
|
||||||
|
|
||||||
//#define DEBUG_BOARD_INIT
|
//#define DEBUG_BOARD_INIT
|
||||||
|
|
||||||
@ -687,10 +689,17 @@ static int64_t load_kernel (CPUState *env)
|
|||||||
int index = 0;
|
int index = 0;
|
||||||
long initrd_size;
|
long initrd_size;
|
||||||
ram_addr_t initrd_offset;
|
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,
|
if (load_elf(loaderparams.kernel_filename, VIRT_TO_PHYS_ADDEND,
|
||||||
(uint64_t *)&kernel_entry, (uint64_t *)&kernel_low,
|
(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",
|
fprintf(stderr, "qemu: could not load kernel '%s'\n",
|
||||||
loaderparams.kernel_filename);
|
loaderparams.kernel_filename);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -32,6 +32,8 @@
|
|||||||
#include "sysemu.h"
|
#include "sysemu.h"
|
||||||
#include "boards.h"
|
#include "boards.h"
|
||||||
#include "mips-bios.h"
|
#include "mips-bios.h"
|
||||||
|
#include "loader.h"
|
||||||
|
#include "elf.h"
|
||||||
|
|
||||||
#ifdef TARGET_MIPS64
|
#ifdef TARGET_MIPS64
|
||||||
#define PHYS_TO_VIRT(x) ((x) | ~0x7fffffffULL)
|
#define PHYS_TO_VIRT(x) ((x) | ~0x7fffffffULL)
|
||||||
@ -54,10 +56,17 @@ static void load_kernel (CPUState *env)
|
|||||||
long kernel_size;
|
long kernel_size;
|
||||||
long initrd_size;
|
long initrd_size;
|
||||||
ram_addr_t initrd_offset;
|
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,
|
kernel_size = load_elf(loaderparams.kernel_filename, VIRT_TO_PHYS_ADDEND,
|
||||||
(uint64_t *)&entry, (uint64_t *)&kernel_low,
|
(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 (kernel_size >= 0) {
|
||||||
if ((entry & ~0x7fffffffULL) == 0x80000000)
|
if ((entry & ~0x7fffffffULL) == 0x80000000)
|
||||||
entry = (int32_t)entry;
|
entry = (int32_t)entry;
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
#include "qemu-log.h"
|
#include "qemu-log.h"
|
||||||
#include "mips-bios.h"
|
#include "mips-bios.h"
|
||||||
#include "ide.h"
|
#include "ide.h"
|
||||||
|
#include "loader.h"
|
||||||
|
#include "elf.h"
|
||||||
|
|
||||||
#define PHYS_TO_VIRT(x) ((x) | ~(target_ulong)0x7fffffff)
|
#define PHYS_TO_VIRT(x) ((x) | ~(target_ulong)0x7fffffff)
|
||||||
|
|
||||||
@ -77,10 +79,16 @@ static void load_kernel (CPUState *env)
|
|||||||
long kernel_size, initrd_size;
|
long kernel_size, initrd_size;
|
||||||
ram_addr_t initrd_offset;
|
ram_addr_t initrd_offset;
|
||||||
int ret;
|
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,
|
kernel_size = load_elf(loaderparams.kernel_filename, VIRT_TO_PHYS_ADDEND,
|
||||||
(uint64_t *)&entry, (uint64_t *)&kernel_low,
|
(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 (kernel_size >= 0) {
|
||||||
if ((entry & ~0x7fffffffULL) == 0x80000000)
|
if ((entry & ~0x7fffffffULL) == 0x80000000)
|
||||||
entry = (int32_t)entry;
|
entry = (int32_t)entry;
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "flash.h"
|
#include "flash.h"
|
||||||
#include "hw.h"
|
#include "hw.h"
|
||||||
#include "bt.h"
|
#include "bt.h"
|
||||||
|
#include "loader.h"
|
||||||
|
|
||||||
/* Nokia N8x0 support */
|
/* Nokia N8x0 support */
|
||||||
struct n800_s {
|
struct n800_s {
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "boards.h"
|
#include "boards.h"
|
||||||
#include "arm-misc.h"
|
#include "arm-misc.h"
|
||||||
#include "devices.h"
|
#include "devices.h"
|
||||||
|
#include "loader.h"
|
||||||
|
|
||||||
static uint32_t static_readb(void *opaque, target_phys_addr_t offset)
|
static uint32_t static_readb(void *opaque, target_phys_addr_t offset)
|
||||||
{
|
{
|
||||||
|
5
hw/pc.c
5
hw/pc.c
@ -37,6 +37,8 @@
|
|||||||
#include "watchdog.h"
|
#include "watchdog.h"
|
||||||
#include "smbios.h"
|
#include "smbios.h"
|
||||||
#include "ide.h"
|
#include "ide.h"
|
||||||
|
#include "loader.h"
|
||||||
|
#include "elf.h"
|
||||||
|
|
||||||
/* output Bochs bios info messages */
|
/* output Bochs bios info messages */
|
||||||
//#define DEBUG_BIOS
|
//#define DEBUG_BIOS
|
||||||
@ -657,7 +659,8 @@ static int load_multiboot(void *fw_cfg,
|
|||||||
uint64_t elf_entry;
|
uint64_t elf_entry;
|
||||||
int kernel_size;
|
int kernel_size;
|
||||||
fclose(f);
|
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) {
|
if (kernel_size < 0) {
|
||||||
fprintf(stderr, "Error while loading elf kernel\n");
|
fprintf(stderr, "Error while loading elf kernel\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -32,6 +32,8 @@
|
|||||||
#include "boards.h"
|
#include "boards.h"
|
||||||
#include "device_tree.h"
|
#include "device_tree.h"
|
||||||
#include "xilinx.h"
|
#include "xilinx.h"
|
||||||
|
#include "loader.h"
|
||||||
|
#include "elf.h"
|
||||||
|
|
||||||
#define LMB_BRAM_SIZE (128 * 1024)
|
#define LMB_BRAM_SIZE (128 * 1024)
|
||||||
#define FLASH_SIZE (16 * 1024 * 1024)
|
#define FLASH_SIZE (16 * 1024 * 1024)
|
||||||
@ -155,11 +157,13 @@ petalogix_s3adsp1800_init(ram_addr_t ram_size,
|
|||||||
|
|
||||||
/* Boots a kernel elf binary. */
|
/* Boots a kernel elf binary. */
|
||||||
kernel_size = load_elf(kernel_filename, 0,
|
kernel_size = load_elf(kernel_filename, 0,
|
||||||
&entry, &low, &high);
|
&entry, &low, &high,
|
||||||
|
1, ELF_MACHINE, 0);
|
||||||
base32 = entry;
|
base32 = entry;
|
||||||
if (base32 == 0xc0000000) {
|
if (base32 == 0xc0000000) {
|
||||||
kernel_size = load_elf(kernel_filename, -0x30000000LL,
|
kernel_size = load_elf(kernel_filename, -0x30000000LL,
|
||||||
&entry, NULL, NULL);
|
&entry, NULL, NULL,
|
||||||
|
1, ELF_MACHINE, 0);
|
||||||
}
|
}
|
||||||
/* Always boot into physical ram. */
|
/* Always boot into physical ram. */
|
||||||
bootstrap_pc = ddr_base + (entry & 0x0fffffff);
|
bootstrap_pc = ddr_base + (entry & 0x0fffffff);
|
||||||
|
1
hw/ppc.c
1
hw/ppc.c
@ -27,6 +27,7 @@
|
|||||||
#include "sysemu.h"
|
#include "sysemu.h"
|
||||||
#include "nvram.h"
|
#include "nvram.h"
|
||||||
#include "qemu-log.h"
|
#include "qemu-log.h"
|
||||||
|
#include "loader.h"
|
||||||
|
|
||||||
//#define PPC_DEBUG_IRQ
|
//#define PPC_DEBUG_IRQ
|
||||||
//#define PPC_DEBUG_TB
|
//#define PPC_DEBUG_TB
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "block.h"
|
#include "block.h"
|
||||||
#include "boards.h"
|
#include "boards.h"
|
||||||
#include "qemu-log.h"
|
#include "qemu-log.h"
|
||||||
|
#include "loader.h"
|
||||||
|
|
||||||
#define BIOS_FILENAME "ppc405_rom.bin"
|
#define BIOS_FILENAME "ppc405_rom.bin"
|
||||||
#define BIOS_SIZE (2048 * 1024)
|
#define BIOS_SIZE (2048 * 1024)
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
#include "kvm.h"
|
#include "kvm.h"
|
||||||
#include "kvm_ppc.h"
|
#include "kvm_ppc.h"
|
||||||
#include "device_tree.h"
|
#include "device_tree.h"
|
||||||
|
#include "loader.h"
|
||||||
|
#include "elf.h"
|
||||||
|
|
||||||
#define BINARY_DEVICE_TREE_FILE "bamboo.dtb"
|
#define BINARY_DEVICE_TREE_FILE "bamboo.dtb"
|
||||||
|
|
||||||
@ -93,8 +95,8 @@ static void bamboo_init(ram_addr_t ram_size,
|
|||||||
CPUState *env;
|
CPUState *env;
|
||||||
uint64_t elf_entry;
|
uint64_t elf_entry;
|
||||||
uint64_t elf_lowaddr;
|
uint64_t elf_lowaddr;
|
||||||
target_ulong entry = 0;
|
target_phys_addr_t entry = 0;
|
||||||
target_ulong loadaddr = 0;
|
target_phys_addr_t loadaddr = 0;
|
||||||
target_long kernel_size = 0;
|
target_long kernel_size = 0;
|
||||||
target_ulong initrd_base = 0;
|
target_ulong initrd_base = 0;
|
||||||
target_long initrd_size = 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);
|
kernel_size = load_uimage(kernel_filename, &entry, &loadaddr, NULL);
|
||||||
if (kernel_size < 0) {
|
if (kernel_size < 0) {
|
||||||
kernel_size = load_elf(kernel_filename, 0, &elf_entry, &elf_lowaddr,
|
kernel_size = load_elf(kernel_filename, 0, &elf_entry, &elf_lowaddr,
|
||||||
NULL);
|
NULL, 1, ELF_MACHINE, 0);
|
||||||
entry = elf_entry;
|
entry = elf_entry;
|
||||||
loadaddr = elf_lowaddr;
|
loadaddr = elf_lowaddr;
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,8 @@
|
|||||||
#include "escc.h"
|
#include "escc.h"
|
||||||
#include "openpic.h"
|
#include "openpic.h"
|
||||||
#include "ide.h"
|
#include "ide.h"
|
||||||
|
#include "loader.h"
|
||||||
|
#include "elf.h"
|
||||||
|
|
||||||
#define MAX_IDE_BUS 2
|
#define MAX_IDE_BUS 2
|
||||||
#define VGA_BIOS_SIZE 65536
|
#define VGA_BIOS_SIZE 65536
|
||||||
@ -145,7 +147,8 @@ static void ppc_core99_init (ram_addr_t ram_size,
|
|||||||
|
|
||||||
/* Load OpenBIOS (ELF) */
|
/* Load OpenBIOS (ELF) */
|
||||||
if (filename) {
|
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);
|
qemu_free(filename);
|
||||||
} else {
|
} else {
|
||||||
bios_size = -1;
|
bios_size = -1;
|
||||||
@ -187,19 +190,28 @@ static void ppc_core99_init (ram_addr_t ram_size,
|
|||||||
|
|
||||||
if (linux_boot) {
|
if (linux_boot) {
|
||||||
uint64_t lowaddr = 0;
|
uint64_t lowaddr = 0;
|
||||||
|
int bswap_needed;
|
||||||
|
|
||||||
|
#ifdef BSWAP_NEEDED
|
||||||
|
bswap_needed = 1;
|
||||||
|
#else
|
||||||
|
bswap_needed = 0;
|
||||||
|
#endif
|
||||||
kernel_base = KERNEL_LOAD_ADDR;
|
kernel_base = KERNEL_LOAD_ADDR;
|
||||||
|
|
||||||
/* Now we can load the kernel. The first step tries to load the kernel
|
/* Now we can load the kernel. The first step tries to load the kernel
|
||||||
supposing PhysAddr = 0x00000000. If that was wrong the kernel is
|
supposing PhysAddr = 0x00000000. If that was wrong the kernel is
|
||||||
loaded again, the new PhysAddr being computed from lowaddr. */
|
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) {
|
if (kernel_size > 0 && lowaddr != KERNEL_LOAD_ADDR) {
|
||||||
kernel_size = load_elf(kernel_filename, (2 * kernel_base) - lowaddr,
|
kernel_size = load_elf(kernel_filename, (2 * kernel_base) - lowaddr,
|
||||||
NULL, NULL, NULL);
|
NULL, NULL, NULL, 1, ELF_MACHINE, 0);
|
||||||
}
|
}
|
||||||
if (kernel_size < 0)
|
if (kernel_size < 0)
|
||||||
kernel_size = load_aout(kernel_filename, kernel_base,
|
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)
|
if (kernel_size < 0)
|
||||||
kernel_size = load_image_targphys(kernel_filename,
|
kernel_size = load_image_targphys(kernel_filename,
|
||||||
kernel_base,
|
kernel_base,
|
||||||
|
@ -36,6 +36,8 @@
|
|||||||
#include "fw_cfg.h"
|
#include "fw_cfg.h"
|
||||||
#include "escc.h"
|
#include "escc.h"
|
||||||
#include "ide.h"
|
#include "ide.h"
|
||||||
|
#include "loader.h"
|
||||||
|
#include "elf.h"
|
||||||
|
|
||||||
#define MAX_IDE_BUS 2
|
#define MAX_IDE_BUS 2
|
||||||
#define VGA_BIOS_SIZE 65536
|
#define VGA_BIOS_SIZE 65536
|
||||||
@ -180,7 +182,8 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
|
|||||||
|
|
||||||
/* Load OpenBIOS (ELF) */
|
/* Load OpenBIOS (ELF) */
|
||||||
if (filename) {
|
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);
|
qemu_free(filename);
|
||||||
} else {
|
} else {
|
||||||
bios_size = -1;
|
bios_size = -1;
|
||||||
@ -222,18 +225,27 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
|
|||||||
|
|
||||||
if (linux_boot) {
|
if (linux_boot) {
|
||||||
uint64_t lowaddr = 0;
|
uint64_t lowaddr = 0;
|
||||||
|
int bswap_needed;
|
||||||
|
|
||||||
|
#ifdef BSWAP_NEEDED
|
||||||
|
bswap_needed = 1;
|
||||||
|
#else
|
||||||
|
bswap_needed = 0;
|
||||||
|
#endif
|
||||||
kernel_base = KERNEL_LOAD_ADDR;
|
kernel_base = KERNEL_LOAD_ADDR;
|
||||||
/* Now we can load the kernel. The first step tries to load the kernel
|
/* Now we can load the kernel. The first step tries to load the kernel
|
||||||
supposing PhysAddr = 0x00000000. If that was wrong the kernel is
|
supposing PhysAddr = 0x00000000. If that was wrong the kernel is
|
||||||
loaded again, the new PhysAddr being computed from lowaddr. */
|
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) {
|
if (kernel_size > 0 && lowaddr != KERNEL_LOAD_ADDR) {
|
||||||
kernel_size = load_elf(kernel_filename, (2 * kernel_base) - lowaddr,
|
kernel_size = load_elf(kernel_filename, (2 * kernel_base) - lowaddr,
|
||||||
NULL, NULL, NULL);
|
NULL, NULL, NULL, 1, ELF_MACHINE, 0);
|
||||||
}
|
}
|
||||||
if (kernel_size < 0)
|
if (kernel_size < 0)
|
||||||
kernel_size = load_aout(kernel_filename, kernel_base,
|
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)
|
if (kernel_size < 0)
|
||||||
kernel_size = load_image_targphys(kernel_filename,
|
kernel_size = load_image_targphys(kernel_filename,
|
||||||
kernel_base,
|
kernel_base,
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include "boards.h"
|
#include "boards.h"
|
||||||
#include "qemu-log.h"
|
#include "qemu-log.h"
|
||||||
#include "ide.h"
|
#include "ide.h"
|
||||||
|
#include "loader.h"
|
||||||
|
|
||||||
//#define HARD_DEBUG_PPC_IO
|
//#define HARD_DEBUG_PPC_IO
|
||||||
//#define DEBUG_PPC_IO
|
//#define DEBUG_PPC_IO
|
||||||
|
@ -29,6 +29,8 @@
|
|||||||
#include "device_tree.h"
|
#include "device_tree.h"
|
||||||
#include "openpic.h"
|
#include "openpic.h"
|
||||||
#include "ppce500.h"
|
#include "ppce500.h"
|
||||||
|
#include "loader.h"
|
||||||
|
#include "elf.h"
|
||||||
|
|
||||||
#define BINARY_DEVICE_TREE_FILE "mpc8544ds.dtb"
|
#define BINARY_DEVICE_TREE_FILE "mpc8544ds.dtb"
|
||||||
#define UIMAGE_LOAD_BASE 0
|
#define UIMAGE_LOAD_BASE 0
|
||||||
@ -160,8 +162,8 @@ static void mpc8544ds_init(ram_addr_t ram_size,
|
|||||||
CPUState *env;
|
CPUState *env;
|
||||||
uint64_t elf_entry;
|
uint64_t elf_entry;
|
||||||
uint64_t elf_lowaddr;
|
uint64_t elf_lowaddr;
|
||||||
target_ulong entry=0;
|
target_phys_addr_t entry=0;
|
||||||
target_ulong loadaddr=UIMAGE_LOAD_BASE;
|
target_phys_addr_t loadaddr=UIMAGE_LOAD_BASE;
|
||||||
target_long kernel_size=0;
|
target_long kernel_size=0;
|
||||||
target_ulong dt_base=DTB_LOAD_BASE;
|
target_ulong dt_base=DTB_LOAD_BASE;
|
||||||
target_ulong initrd_base=INITRD_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);
|
kernel_size = load_uimage(kernel_filename, &entry, &loadaddr, NULL);
|
||||||
if (kernel_size < 0) {
|
if (kernel_size < 0) {
|
||||||
kernel_size = load_elf(kernel_filename, 0, &elf_entry, &elf_lowaddr,
|
kernel_size = load_elf(kernel_filename, 0, &elf_entry, &elf_lowaddr,
|
||||||
NULL);
|
NULL, 1, ELF_MACHINE, 0);
|
||||||
entry = elf_entry;
|
entry = elf_entry;
|
||||||
loadaddr = elf_lowaddr;
|
loadaddr = elf_lowaddr;
|
||||||
}
|
}
|
||||||
|
1
hw/r2d.c
1
hw/r2d.c
@ -32,6 +32,7 @@
|
|||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "sh7750_regs.h"
|
#include "sh7750_regs.h"
|
||||||
#include "ide.h"
|
#include "ide.h"
|
||||||
|
#include "loader.h"
|
||||||
|
|
||||||
#define SDRAM_BASE 0x0c000000 /* Physical location of SDRAM: Area 3 */
|
#define SDRAM_BASE 0x0c000000 /* Physical location of SDRAM: Area 3 */
|
||||||
#define SDRAM_SIZE 0x04000000
|
#define SDRAM_SIZE 0x04000000
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
#include "sysemu.h"
|
#include "sysemu.h"
|
||||||
#include "boards.h"
|
#include "boards.h"
|
||||||
|
#include "loader.h"
|
||||||
|
|
||||||
#define BIOS_FILENAME "shix_bios.bin"
|
#define BIOS_FILENAME "shix_bios.bin"
|
||||||
#define BIOS_ADDRESS 0xA0000000
|
#define BIOS_ADDRESS 0xA0000000
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include "sysemu.h"
|
#include "sysemu.h"
|
||||||
#include "smbios.h"
|
#include "smbios.h"
|
||||||
|
#include "loader.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Structures shared with the BIOS
|
* Structures shared with the BIOS
|
||||||
|
17
hw/sun4m.c
17
hw/sun4m.c
@ -37,6 +37,8 @@
|
|||||||
#include "fw_cfg.h"
|
#include "fw_cfg.h"
|
||||||
#include "escc.h"
|
#include "escc.h"
|
||||||
#include "qdev-addr.h"
|
#include "qdev-addr.h"
|
||||||
|
#include "loader.h"
|
||||||
|
#include "elf.h"
|
||||||
|
|
||||||
//#define DEBUG_IRQ
|
//#define DEBUG_IRQ
|
||||||
|
|
||||||
@ -302,11 +304,19 @@ static unsigned long sun4m_load_kernel(const char *kernel_filename,
|
|||||||
|
|
||||||
kernel_size = 0;
|
kernel_size = 0;
|
||||||
if (linux_boot) {
|
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,
|
kernel_size = load_elf(kernel_filename, -0xf0000000ULL, NULL, NULL,
|
||||||
NULL);
|
NULL, 1, ELF_MACHINE, 0);
|
||||||
if (kernel_size < 0)
|
if (kernel_size < 0)
|
||||||
kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR,
|
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)
|
if (kernel_size < 0)
|
||||||
kernel_size = load_image_targphys(kernel_filename,
|
kernel_size = load_image_targphys(kernel_filename,
|
||||||
KERNEL_LOAD_ADDR,
|
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);
|
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
|
||||||
if (filename) {
|
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) {
|
if (ret < 0 || ret > PROM_SIZE_MAX) {
|
||||||
ret = load_image_targphys(filename, addr, PROM_SIZE_MAX);
|
ret = load_image_targphys(filename, addr, PROM_SIZE_MAX);
|
||||||
}
|
}
|
||||||
|
18
hw/sun4u.c
18
hw/sun4u.c
@ -34,6 +34,8 @@
|
|||||||
#include "fw_cfg.h"
|
#include "fw_cfg.h"
|
||||||
#include "sysbus.h"
|
#include "sysbus.h"
|
||||||
#include "ide.h"
|
#include "ide.h"
|
||||||
|
#include "loader.h"
|
||||||
|
#include "elf.h"
|
||||||
|
|
||||||
//#define DEBUG_IRQ
|
//#define DEBUG_IRQ
|
||||||
|
|
||||||
@ -164,10 +166,19 @@ static unsigned long sun4u_load_kernel(const char *kernel_filename,
|
|||||||
|
|
||||||
kernel_size = 0;
|
kernel_size = 0;
|
||||||
if (linux_boot) {
|
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)
|
if (kernel_size < 0)
|
||||||
kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR,
|
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)
|
if (kernel_size < 0)
|
||||||
kernel_size = load_image_targphys(kernel_filename,
|
kernel_size = load_image_targphys(kernel_filename,
|
||||||
KERNEL_LOAD_ADDR,
|
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);
|
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
|
||||||
if (filename) {
|
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) {
|
if (ret < 0 || ret > PROM_SIZE_MAX) {
|
||||||
ret = load_image_targphys(filename, addr, PROM_SIZE_MAX);
|
ret = load_image_targphys(filename, addr, PROM_SIZE_MAX);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "hw.h"
|
#include "hw.h"
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
#include "sysemu.h"
|
#include "sysemu.h"
|
||||||
|
#include "loader.h"
|
||||||
|
|
||||||
#define CE1 0x0100
|
#define CE1 0x0100
|
||||||
#define CE2 0x0200
|
#define CE2 0x0200
|
||||||
|
@ -1315,10 +1315,10 @@ static void load_symbols(struct elfhdr *hdr, int fd)
|
|||||||
s->disas_num_syms = nsyms;
|
s->disas_num_syms = nsyms;
|
||||||
#if ELF_CLASS == ELFCLASS32
|
#if ELF_CLASS == ELFCLASS32
|
||||||
s->disas_symtab.elf32 = syms;
|
s->disas_symtab.elf32 = syms;
|
||||||
s->lookup_symbol = lookup_symbolxx;
|
s->lookup_symbol = (lookup_symbol_t)lookup_symbolxx;
|
||||||
#else
|
#else
|
||||||
s->disas_symtab.elf64 = syms;
|
s->disas_symtab.elf64 = syms;
|
||||||
s->lookup_symbol = lookup_symbolxx;
|
s->lookup_symbol = (lookup_symbol_t)lookup_symbolxx;
|
||||||
#endif
|
#endif
|
||||||
s->next = syminfos;
|
s->next = syminfos;
|
||||||
syminfos = s;
|
syminfos = s;
|
||||||
|
18
sysemu.h
18
sysemu.h
@ -237,24 +237,6 @@ extern CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
|
|||||||
|
|
||||||
#define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
|
#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
|
#ifdef HAS_AUDIO
|
||||||
struct soundhw {
|
struct soundhw {
|
||||||
const char *name;
|
const char *name;
|
||||||
|
Loading…
Reference in New Issue
Block a user