提交 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 ...@@ -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 ...@@ -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
......
...@@ -3,6 +3,7 @@ ...@@ -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, ...@@ -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 @@ ...@@ -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, ...@@ -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, ...@@ -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 @@ ...@@ -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) ...@@ -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) ...@@ -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,
......
...@@ -10,6 +10,8 @@ ...@@ -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, ...@@ -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, ...@@ -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 @@ ...@@ -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, ...@@ -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 @@ ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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 @@ ...@@ -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, ...@@ -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 @@ ...@@ -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 ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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;
bswap_ahdr(&e); if (bswap_needed) {
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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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;
......
#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 @@ ...@@ -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, ...@@ -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, ...@@ -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 @@ ...@@ -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 @@ ...@@ -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) ...@@ -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 @@ ...@@ -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) ...@@ -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 @@ ...@@ -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) ...@@ -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 @@ ...@@ -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 @@ ...@@ -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)
{ {
......
...@@ -37,6 +37,8 @@ ...@@ -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, ...@@ -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 @@ ...@@ -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, ...@@ -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);
......
...@@ -27,6 +27,7 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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, ...@@ -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, ...@@ -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 @@ ...@@ -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, ...@@ -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, ...@@ -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 @@ ...@@ -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, ...@@ -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, ...@@ -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 @@ ...@@ -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 @@ ...@@ -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, ...@@ -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, ...@@ -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;
} }
......
...@@ -32,6 +32,7 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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
......
...@@ -37,6 +37,8 @@ ...@@ -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, ...@@ -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) ...@@ -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);
} }
......
...@@ -34,6 +34,8 @@ ...@@ -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, ...@@ -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) ...@@ -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);
} }
......
#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) ...@@ -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;
......
...@@ -237,24 +237,6 @@ extern CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES]; ...@@ -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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册