Add a.out support for SILO

git-svn-id: svn://coreboot.org/openbios/openbios-devel@196 f158a5a8-5612-0410-a976-696ce0be7e32
This commit is contained in:
Blue Swirl
2008-07-08 16:02:43 +00:00
parent 61d79955b5
commit 57aabd8563
4 changed files with 152 additions and 2 deletions

146
arch/sparc64/aoutload.c Normal file
View File

@@ -0,0 +1,146 @@
/* a.out boot loader
* As we have seek, this implementation can be straightforward.
* 2003-07 by SONE Takeshi
*/
#include "openbios/config.h"
#include "openbios/kernel.h"
#define CONFIG_SPARC64_PAGE_SIZE_8KB
#include "a.out.h"
#include "sys_info.h"
#include "loadfs.h"
#include "boot.h"
#define printf printk
#define debug printk
#define addr_fixup(addr) ((addr) & 0x00ffffff)
static char *image_name, *image_version;
const char *program_name, *program_version;
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 char *cmdline)
{
int retval = -1;
int image_retval;
struct exec ehdr;
unsigned long start, size;
unsigned int offset;
image_name = image_version = 0;
if (!file_open(filename))
goto out;
for (offset = 0; offset < 16 * 512; offset += 512) {
file_seek(offset);
if (lfile_read(&ehdr, sizeof ehdr) != sizeof ehdr) {
debug("Can't read a.out header\n");
retval = LOADER_NOT_SUPPORT;
goto out;
}
if (!N_BADMAG(ehdr))
break;
}
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");
file_seek(offset + N_TXTOFF(ehdr));
if (N_MAGIC(ehdr) == NMAGIC) {
if ((unsigned long)lfile_read((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)lfile_read((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)lfile_read((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);
printf("Jumping to entry point...\n");
#if 1
{
int (*entry)(unsigned long p1, unsigned long p2, unsigned long p3,
unsigned long p4, unsigned long p5);
extern int of_client_interface( int *params );
entry = (void *) addr_fixup(start);
image_retval = entry(0, 0, 0, 0, (unsigned long)&of_client_interface);
}
#endif
printf("Image returned with return value %#x\n", image_retval);
retval = 0;
out:
file_close();
return retval;
}

View File

@@ -67,13 +67,15 @@ void boot(void)
if (elf_load(&sys_info, path, param) == LOADER_NOT_SUPPORT)
if (linux_load(&sys_info, path, param) == LOADER_NOT_SUPPORT) {
if (linux_load(&sys_info, path, param) == LOADER_NOT_SUPPORT)
if (aout_load(&sys_info, path, param) == LOADER_NOT_SUPPORT) {
sprintf(altpath, "%s:d", path);
if (elf_load(&sys_info, altpath, param) == LOADER_NOT_SUPPORT)
if (linux_load(&sys_info, altpath, param) == LOADER_NOT_SUPPORT)
printk("Unsupported image format\n");
if (aout_load(&sys_info, altpath, param) == LOADER_NOT_SUPPORT)
printk("Unsupported image format\n");
}
free(path);

View File

@@ -9,6 +9,7 @@
int forth_load(struct sys_info *info, const char *filename, const char *cmdline);
int elf_load(struct sys_info *info, const char *filename, const char *cmdline);
int linux_load(struct sys_info *info, const char *file, const char *cmdline);
int aout_load(struct sys_info *info, const char *filename, const char *cmdline);
uint64_t start_elf(uint64_t entry_point, uint64_t param);

View File

@@ -15,6 +15,7 @@
<object source="linux_load.c"/>
<object source="sys_info.c"/>
<object source="elfload.c"/>
<object source="aoutload.c"/>
<object source="forthload.c"/>
<object source="loadfs.c"/>
</library>