mirror of
https://gitlab.com/qemu-project/openbios.git
synced 2024-02-13 08:34:06 +08:00
Move the a.out loader from arch/*/aoutload.c into libopenbios as aout_load.c.
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@siriusit.co.uk> git-svn-id: svn://coreboot.org/openbios/trunk/openbios-devel@711 f158a5a8-5612-0410-a976-696ce0be7e32
This commit is contained in:
committed by
Mark Cave-Ayland
parent
1264ad95d2
commit
f02d2bde53
@@ -1,141 +0,0 @@
|
|||||||
/* a.out boot loader
|
|
||||||
* As we have seek, this implementation can be straightforward.
|
|
||||||
* 2003-07 by SONE Takeshi
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "kernel/kernel.h"
|
|
||||||
#include "arch/common/a.out.h"
|
|
||||||
#include "libopenbios/sys_info.h"
|
|
||||||
#include "libopenbios/bindings.h"
|
|
||||||
#include "libc/diskio.h"
|
|
||||||
#include "boot.h"
|
|
||||||
#define printf printk
|
|
||||||
#define debug printk
|
|
||||||
|
|
||||||
#define addr_fixup(addr) ((addr) & 0x00ffffff)
|
|
||||||
|
|
||||||
static char *image_name, *image_version;
|
|
||||||
static int fd;
|
|
||||||
|
|
||||||
static int check_mem_ranges(struct sys_info *info,
|
|
||||||
unsigned long start,
|
|
||||||
unsigned long size)
|
|
||||||
{
|
|
||||||
int j;
|
|
||||||
unsigned long end;
|
|
||||||
unsigned long prog_start, prog_end;
|
|
||||||
struct memrange *mem;
|
|
||||||
|
|
||||||
prog_start = virt_to_phys(&_start);
|
|
||||||
prog_end = virt_to_phys(&_end);
|
|
||||||
|
|
||||||
end = start + size;
|
|
||||||
|
|
||||||
if (start < prog_start && end > prog_start)
|
|
||||||
goto conflict;
|
|
||||||
if (start < prog_end && end > prog_end)
|
|
||||||
goto conflict;
|
|
||||||
mem = info->memrange;
|
|
||||||
for (j = 0; j < info->n_memranges; j++) {
|
|
||||||
if (mem[j].base <= start && mem[j].base + mem[j].size >= end)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (j >= info->n_memranges)
|
|
||||||
goto badseg;
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
conflict:
|
|
||||||
printf("%s occupies [%#lx-%#lx]\n", program_name, prog_start, prog_end);
|
|
||||||
|
|
||||||
badseg:
|
|
||||||
printf("A.out file [%#lx-%#lx] doesn't fit into memory\n", start, end - 1);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int aout_load(struct sys_info *info, const char *filename, const void *romvec)
|
|
||||||
{
|
|
||||||
int retval = -1;
|
|
||||||
struct exec ehdr;
|
|
||||||
unsigned long start, size;
|
|
||||||
unsigned int offset = 512;
|
|
||||||
|
|
||||||
image_name = image_version = NULL;
|
|
||||||
|
|
||||||
/* Mark the saved-program-state as invalid */
|
|
||||||
feval("0 state-valid !");
|
|
||||||
|
|
||||||
fd = open_io(filename);
|
|
||||||
if (!fd)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
seek_io(fd, offset);
|
|
||||||
|
|
||||||
if (read_io(fd, &ehdr, sizeof ehdr) != sizeof ehdr) {
|
|
||||||
debug("Can't read a.out header\n");
|
|
||||||
retval = LOADER_NOT_SUPPORT;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (N_BADMAG(ehdr)) {
|
|
||||||
debug("Not a bootable a.out image\n");
|
|
||||||
retval = LOADER_NOT_SUPPORT;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ehdr.a_text == 0x30800007)
|
|
||||||
ehdr.a_text=64*1024;
|
|
||||||
|
|
||||||
if (N_MAGIC(ehdr) == NMAGIC) {
|
|
||||||
size = addr_fixup(N_DATADDR(ehdr)) + addr_fixup(ehdr.a_data);
|
|
||||||
} else {
|
|
||||||
size = addr_fixup(ehdr.a_text) + addr_fixup(ehdr.a_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size < 7680)
|
|
||||||
size = 7680;
|
|
||||||
|
|
||||||
|
|
||||||
start = 0x4000; // N_TXTADDR(ehdr);
|
|
||||||
|
|
||||||
if (!check_mem_ranges(info, start, size))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
printf("Loading a.out %s...\n", image_name ? image_name : "image");
|
|
||||||
|
|
||||||
seek_io(fd, offset + N_TXTOFF(ehdr));
|
|
||||||
|
|
||||||
if (N_MAGIC(ehdr) == NMAGIC) {
|
|
||||||
if ((unsigned long)read_io(fd, (void *)start, ehdr.a_text) != ehdr.a_text) {
|
|
||||||
printf("Can't read program text segment (size 0x%lx)\n", ehdr.a_text);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if ((unsigned long)read_io(fd, (void *)(start + N_DATADDR(ehdr)), ehdr.a_data) != ehdr.a_data) {
|
|
||||||
printf("Can't read program data segment (size 0x%lx)\n", ehdr.a_data);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ((unsigned long)read_io(fd, (void *)start, size) != size) {
|
|
||||||
printf("Can't read program (size 0x%lx)\n", size);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
debug("Loaded %lu bytes\n", size);
|
|
||||||
debug("entry point is %#lx\n", start);
|
|
||||||
|
|
||||||
// Initialise saved-program-state
|
|
||||||
PUSH(addr_fixup(start));
|
|
||||||
feval("saved-program-state >sps.entry !");
|
|
||||||
PUSH(size);
|
|
||||||
feval("saved-program-state >sps.file-size !");
|
|
||||||
feval("aout saved-program-state >sps.file-type !");
|
|
||||||
|
|
||||||
feval("-1 state-valid !");
|
|
||||||
|
|
||||||
retval = 0;
|
|
||||||
|
|
||||||
out:
|
|
||||||
close_io(fd);
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
@@ -9,6 +9,8 @@
|
|||||||
#include "libc/diskio.h"
|
#include "libc/diskio.h"
|
||||||
#include "libc/vsprintf.h"
|
#include "libc/vsprintf.h"
|
||||||
#include "libopenbios/sys_info.h"
|
#include "libopenbios/sys_info.h"
|
||||||
|
#include "libopenbios/elf_load.h"
|
||||||
|
#include "libopenbios/aout_load.h"
|
||||||
#include "openprom.h"
|
#include "openprom.h"
|
||||||
#include "boot.h"
|
#include "boot.h"
|
||||||
|
|
||||||
@@ -22,6 +24,7 @@ int (*entry)(const void *romvec_ptr, int p2, int p3, int p4, int p5);
|
|||||||
|
|
||||||
static int try_path(const char *path, char *param, const void *romvec)
|
static int try_path(const char *path, char *param, const void *romvec)
|
||||||
{
|
{
|
||||||
|
void *boot_notes = NULL;
|
||||||
ucell valid, address, type, size;
|
ucell valid, address, type, size;
|
||||||
int image_retval = 0;
|
int image_retval = 0;
|
||||||
|
|
||||||
@@ -31,7 +34,7 @@ static int try_path(const char *path, char *param, const void *romvec)
|
|||||||
printk("Trying %s (%s)\n", path, bootpath);
|
printk("Trying %s (%s)\n", path, bootpath);
|
||||||
|
|
||||||
/* ELF Boot loader */
|
/* ELF Boot loader */
|
||||||
elf_load(&sys_info, path, param, romvec);
|
elf_load(&sys_info, path, param, &boot_notes);
|
||||||
feval("state-valid @");
|
feval("state-valid @");
|
||||||
valid = POP();
|
valid = POP();
|
||||||
if (valid)
|
if (valid)
|
||||||
@@ -41,7 +44,7 @@ static int try_path(const char *path, char *param, const void *romvec)
|
|||||||
linux_load(&sys_info, path, param);
|
linux_load(&sys_info, path, param);
|
||||||
|
|
||||||
/* a.out loader */
|
/* a.out loader */
|
||||||
aout_load(&sys_info, path, romvec);
|
aout_load(&sys_info, path);
|
||||||
feval("state-valid @");
|
feval("state-valid @");
|
||||||
valid = POP();
|
valid = POP();
|
||||||
if (valid)
|
if (valid)
|
||||||
|
|||||||
@@ -9,13 +9,6 @@
|
|||||||
// forthload.c
|
// forthload.c
|
||||||
int forth_load(const char *filename);
|
int forth_load(const char *filename);
|
||||||
|
|
||||||
// elfload.c
|
|
||||||
int elf_load(struct sys_info *, const char *filename, const char *cmdline,
|
|
||||||
const void *romvec);
|
|
||||||
|
|
||||||
// aout_load.c
|
|
||||||
int aout_load(struct sys_info *info, const char *filename, const void *romvec);
|
|
||||||
|
|
||||||
// linux_load.c
|
// linux_load.c
|
||||||
int linux_load(struct sys_info *info, const char *file, const char *cmdline);
|
int linux_load(struct sys_info *info, const char *file, const char *cmdline);
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
<object source="udiv.S"/>
|
<object source="udiv.S"/>
|
||||||
<object source="linux_load.c"/>
|
<object source="linux_load.c"/>
|
||||||
<object source="sys_info.c"/>
|
<object source="sys_info.c"/>
|
||||||
<object source="aoutload.c"/>
|
|
||||||
<object source="forthload.c"/>
|
<object source="forthload.c"/>
|
||||||
<object source="romvec.c"/>
|
<object source="romvec.c"/>
|
||||||
<object source="entry.S"/>
|
<object source="entry.S"/>
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "libc/vsprintf.h"
|
#include "libc/vsprintf.h"
|
||||||
#include "libopenbios/sys_info.h"
|
#include "libopenbios/sys_info.h"
|
||||||
#include "libopenbios/elf_load.h"
|
#include "libopenbios/elf_load.h"
|
||||||
|
#include "libopenbios/aout_load.h"
|
||||||
#include "boot.h"
|
#include "boot.h"
|
||||||
|
|
||||||
struct sys_info sys_info;
|
struct sys_info sys_info;
|
||||||
|
|||||||
@@ -9,9 +9,6 @@
|
|||||||
// forthload.c
|
// forthload.c
|
||||||
int forth_load(const char *filename);
|
int forth_load(const char *filename);
|
||||||
|
|
||||||
// aout_load.c
|
|
||||||
int aout_load(struct sys_info *info, const char *filename);
|
|
||||||
|
|
||||||
// linux_load.c
|
// linux_load.c
|
||||||
int linux_load(struct sys_info *info, const char *file, const char *cmdline);
|
int linux_load(struct sys_info *info, const char *file, const char *cmdline);
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
<object source="switch.S"/>
|
<object source="switch.S"/>
|
||||||
<object source="linux_load.c"/>
|
<object source="linux_load.c"/>
|
||||||
<object source="sys_info.c"/>
|
<object source="sys_info.c"/>
|
||||||
<object source="aoutload.c"/>
|
|
||||||
<object source="forthload.c"/>
|
<object source="forthload.c"/>
|
||||||
<object source="fcodeload.c"/>
|
<object source="fcodeload.c"/>
|
||||||
<object source="ofmem_sparc64.c"/>
|
<object source="ofmem_sparc64.c"/>
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ typedef unsigned long long ducell;
|
|||||||
#define FMT_ucellX "%08X"
|
#define FMT_ucellX "%08X"
|
||||||
|
|
||||||
#define FMT_elf "%#x"
|
#define FMT_elf "%#x"
|
||||||
|
#define FMT_sizet "%lx"
|
||||||
|
#define FMT_aout_ehdr "%lx"
|
||||||
|
|
||||||
#define bitspercell (sizeof(cell)<<3)
|
#define bitspercell (sizeof(cell)<<3)
|
||||||
#define bitsperdcell (sizeof(dcell)<<3)
|
#define bitsperdcell (sizeof(dcell)<<3)
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ typedef unsigned long long ucell;
|
|||||||
#define FMT_ucellx "%016llx"
|
#define FMT_ucellx "%016llx"
|
||||||
#define FMT_ucellX "%016llX"
|
#define FMT_ucellX "%016llX"
|
||||||
|
|
||||||
#define FMT_sizet "%lx"
|
|
||||||
#define FMT_elf "%#llx"
|
#define FMT_elf "%#llx"
|
||||||
|
#define FMT_sizet "%lx"
|
||||||
#define FMT_aout_ehdr "%x"
|
#define FMT_aout_ehdr "%x"
|
||||||
|
|
||||||
#ifdef NEED_FAKE_INT128_T
|
#ifdef NEED_FAKE_INT128_T
|
||||||
|
|||||||
24
include/libopenbios/aout_load.h
Normal file
24
include/libopenbios/aout_load.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* Creation Date: <2010/03/22 18:00:00 mcayland>
|
||||||
|
* Time-stamp: <2010/03/22 18:00:00 mcayland>
|
||||||
|
*
|
||||||
|
* <aout_load.h>
|
||||||
|
*
|
||||||
|
* a.out loader
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Mark Cave-Ayland (mark.cave-ayland@siriusit.co.uk)
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _H_AOUTLOAD
|
||||||
|
#define _H_AOUTLOAD
|
||||||
|
|
||||||
|
#include "libopenbios/sys_info.h"
|
||||||
|
|
||||||
|
extern int aout_load(struct sys_info *info, const char *filename);
|
||||||
|
|
||||||
|
#endif /* _H_AOUTLOAD */
|
||||||
@@ -5,12 +5,16 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "kernel/kernel.h"
|
#include "kernel/kernel.h"
|
||||||
|
|
||||||
|
#ifdef CONFIG_SPARC64
|
||||||
#define CONFIG_SPARC64_PAGE_SIZE_8KB
|
#define CONFIG_SPARC64_PAGE_SIZE_8KB
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "arch/common/a.out.h"
|
#include "arch/common/a.out.h"
|
||||||
#include "libopenbios/sys_info.h"
|
#include "libopenbios/sys_info.h"
|
||||||
#include "libopenbios/bindings.h"
|
#include "libopenbios/bindings.h"
|
||||||
|
#include "libopenbios/aout_load.h"
|
||||||
#include "libc/diskio.h"
|
#include "libc/diskio.h"
|
||||||
#include "boot.h"
|
|
||||||
#define printf printk
|
#define printf printk
|
||||||
#define debug printk
|
#define debug printk
|
||||||
|
|
||||||
@@ -110,17 +114,17 @@ int aout_load(struct sys_info *info, const char *filename)
|
|||||||
seek_io(fd, offset + N_TXTOFF(ehdr));
|
seek_io(fd, offset + N_TXTOFF(ehdr));
|
||||||
|
|
||||||
if (N_MAGIC(ehdr) == NMAGIC) {
|
if (N_MAGIC(ehdr) == NMAGIC) {
|
||||||
if ((unsigned long)read_io(fd, (void *)start, ehdr.a_text) != ehdr.a_text) {
|
if ((size_t)read_io(fd, (void *)start, ehdr.a_text) != ehdr.a_text) {
|
||||||
printf("Can't read program text segment (size 0x%x)\n", ehdr.a_text);
|
printf("Can't read program text segment (size 0x" FMT_aout_ehdr ")\n", ehdr.a_text);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if ((unsigned long)read_io(fd, (void *)(start + N_DATADDR(ehdr)), ehdr.a_data) != ehdr.a_data) {
|
if ((size_t)read_io(fd, (void *)(start + N_DATADDR(ehdr)), ehdr.a_data) != ehdr.a_data) {
|
||||||
printf("Can't read program data segment (size 0x%x)\n", ehdr.a_data);
|
printf("Can't read program data segment (size 0x" FMT_aout_ehdr ")\n", ehdr.a_data);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((unsigned long)read_io(fd, (void *)start, size) != size) {
|
if ((size_t)read_io(fd, (void *)start, size) != size) {
|
||||||
printf("Can't read program (size 0x%lx)\n", size);
|
printf("Can't read program (size 0x" FMT_sizet ")\n", size);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -137,8 +141,6 @@ int aout_load(struct sys_info *info, const char *filename)
|
|||||||
|
|
||||||
feval("-1 state-valid !");
|
feval("-1 state-valid !");
|
||||||
|
|
||||||
retval = 0;
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
close_io(fd);
|
close_io(fd);
|
||||||
return retval;
|
return retval;
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
<build>
|
<build>
|
||||||
|
|
||||||
<library name="openbios" type="static" target="target">
|
<library name="openbios" type="static" target="target">
|
||||||
|
<object source="aout_load.c" condition="SPARC32"/>
|
||||||
|
<object source="aout_load.c" condition="SPARC64"/>
|
||||||
<object source="bindings.c"/>
|
<object source="bindings.c"/>
|
||||||
<object source="client.c"/>
|
<object source="client.c"/>
|
||||||
<object source="console_common.c"/>
|
<object source="console_common.c"/>
|
||||||
|
|||||||
Reference in New Issue
Block a user