mirror of
https://gitlab.com/qemu-project/openbios.git
synced 2024-02-13 08:34:06 +08:00
Implement a basic C loader function in load.c that tries to load each supported executable file format. Now that the ihandle
hierarchy is correct, we can simply pass an ihandle into the loader and it will work correctly regardless of whether it is being invoked on an entire disk, partition or individual file. In order to test the new code, start by switching the Fcode loader over to the new infrastructure for testing on SPARC64. Note this patch also contains a correction to load-base on SPARC which was being set to a value other than 0x4000 which is the documented default. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@siriusit.co.uk> git-svn-id: svn://coreboot.org/openbios/trunk/openbios-devel@798 f158a5a8-5612-0410-a976-696ce0be7e32
This commit is contained in:
committed by
Mark Cave-Ayland
parent
add30adb7d
commit
3d7832bba9
@@ -30,12 +30,16 @@ static int try_path(const char *path, char *param)
|
||||
{
|
||||
void *boot_notes = NULL;
|
||||
ucell valid;
|
||||
ihandle_t dev;
|
||||
|
||||
push_str(path);
|
||||
fword("pathres-resolve-aliases");
|
||||
bootpath = pop_fstr_copy();
|
||||
printk("Trying %s (%s)\n", path, bootpath);
|
||||
|
||||
/* Open device used by this path */
|
||||
dev = open_dev(path);
|
||||
|
||||
#ifdef CONFIG_LOADER_ELF
|
||||
/* ELF Boot loader */
|
||||
elf_load(&sys_info, path, param, &boot_notes);
|
||||
@@ -59,7 +63,7 @@ static int try_path(const char *path, char *param)
|
||||
|
||||
#ifdef CONFIG_LOADER_FCODE
|
||||
/* Fcode loader */
|
||||
fcode_load(path);
|
||||
fcode_load(dev);
|
||||
feval("state-valid @");
|
||||
valid = POP();
|
||||
if (valid)
|
||||
@@ -75,6 +79,8 @@ static int try_path(const char *path, char *param)
|
||||
goto start_image;
|
||||
#endif
|
||||
|
||||
close_dev(dev);
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
|
||||
@@ -27,6 +27,10 @@ extern int sparc64_of_client_interface( int *params );
|
||||
static int try_path(const char *path, char *param)
|
||||
{
|
||||
ucell valid;
|
||||
ihandle_t dev;
|
||||
|
||||
/* Open device used by this path */
|
||||
dev = open_dev(path);
|
||||
|
||||
#ifdef CONFIG_LOADER_ELF
|
||||
/* ELF Boot loader */
|
||||
@@ -51,7 +55,7 @@ static int try_path(const char *path, char *param)
|
||||
|
||||
#ifdef CONFIG_LOADER_FCODE
|
||||
/* Fcode loader */
|
||||
fcode_load(path);
|
||||
fcode_load(dev);
|
||||
feval("state-valid @");
|
||||
valid = POP();
|
||||
if (valid)
|
||||
@@ -67,6 +71,8 @@ static int try_path(const char *path, char *param)
|
||||
goto start_image;
|
||||
#endif
|
||||
|
||||
close_dev(dev);
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
|
||||
@@ -24,6 +24,10 @@ void *boot_notes = NULL;
|
||||
static int try_path(const char *path, char *param)
|
||||
{
|
||||
ucell valid;
|
||||
ihandle_t dev;
|
||||
|
||||
/* Open device used by this path */
|
||||
dev = open_dev(path);
|
||||
|
||||
#ifdef CONFIG_LOADER_ELF
|
||||
/* ELF Boot loader */
|
||||
@@ -48,7 +52,7 @@ static int try_path(const char *path, char *param)
|
||||
|
||||
#ifdef CONFIG_LOADER_FCODE
|
||||
/* Fcode loader */
|
||||
fcode_load(path);
|
||||
fcode_load(dev);
|
||||
feval("state-valid @");
|
||||
valid = POP();
|
||||
if (valid)
|
||||
@@ -64,6 +68,8 @@ static int try_path(const char *path, char *param)
|
||||
goto start_image;
|
||||
#endif
|
||||
|
||||
close_dev(dev);
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
|
||||
@@ -358,7 +358,7 @@ s" false" s" ttyb-rts-dtr-off" bool-config
|
||||
|
||||
[IFDEF] CONFIG_SPARC64
|
||||
\ ---- SPARC64 ----
|
||||
s" 4000000" s" load-base" int-config
|
||||
s" 4000" s" load-base" int-config
|
||||
s" false" s" little-endian?" bool-config
|
||||
[THEN]
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#define _H_FCODELOAD
|
||||
|
||||
extern int is_fcode(unsigned char *fcode);
|
||||
extern int fcode_load(const char *filename);
|
||||
extern int fcode_load(ihandle_t dev);
|
||||
extern void fcode_init_program(void);
|
||||
|
||||
#endif /* _H_FCODELOAD */
|
||||
|
||||
22
include/libopenbios/load.h
Normal file
22
include/libopenbios/load.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Creation Date: <2010/06/25 20:00:00 mcayland>
|
||||
* Time-stamp: <2010/06/25 20:00:00 mcayland>
|
||||
*
|
||||
* <load.h>
|
||||
*
|
||||
* C implementation of load
|
||||
*
|
||||
* 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
|
||||
* version 2
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _H_LOAD
|
||||
#define _H_LOAD
|
||||
|
||||
extern void load(ihandle_t dev);
|
||||
|
||||
#endif /* _H_LOAD */
|
||||
@@ -15,6 +15,7 @@
|
||||
<object source="init.c"/>
|
||||
<object source="initprogram.c"/>
|
||||
<object source="ipchecksum.c"/>
|
||||
<object source="load.c"/>
|
||||
<object source="linuxbios_info.c" condition="LINUXBIOS"/>
|
||||
<object source="ofmem_common.c" condition="OFMEM"/>
|
||||
<object source="xcoff_load.c" condition="LOADER_XCOFF"/>
|
||||
|
||||
@@ -24,7 +24,7 @@ is_fcode(unsigned char *fcode)
|
||||
}
|
||||
|
||||
int
|
||||
fcode_load(const char *filename)
|
||||
fcode_load(ihandle_t dev)
|
||||
{
|
||||
int retval = -1;
|
||||
uint8_t fcode_header[8];
|
||||
@@ -34,7 +34,7 @@ fcode_load(const char *filename)
|
||||
/* Mark the saved-program-state as invalid */
|
||||
feval("0 state-valid !");
|
||||
|
||||
fd = open_io(filename);
|
||||
fd = open_ih(dev);
|
||||
if (!fd)
|
||||
goto out;
|
||||
|
||||
@@ -42,7 +42,7 @@ fcode_load(const char *filename)
|
||||
seek_io(fd, offset);
|
||||
if (read_io(fd, &fcode_header, sizeof(fcode_header))
|
||||
!= sizeof(fcode_header)) {
|
||||
debug("Can't read FCode header from file %s\n", filename);
|
||||
debug("Can't read FCode header from ihandle " FMT_ucellx "\n", dev);
|
||||
retval = LOADER_NOT_SUPPORT;
|
||||
goto out;
|
||||
}
|
||||
@@ -59,11 +59,12 @@ fcode_load(const char *filename)
|
||||
size = (fcode_header[4] << 24) | (fcode_header[5] << 16) |
|
||||
(fcode_header[6] << 8) | fcode_header[7];
|
||||
|
||||
start = 0x4000;
|
||||
fword("load-base");
|
||||
start = POP();
|
||||
|
||||
printf("Loading FCode image...\n");
|
||||
printf("\nLoading FCode image...\n");
|
||||
|
||||
seek_io(fd, offset + sizeof(fcode_header));
|
||||
seek_io(fd, offset);
|
||||
|
||||
if ((size_t)read_io(fd, (void *)start, size) != size) {
|
||||
printf("Can't read file (size 0x%lx)\n", size);
|
||||
@@ -92,6 +93,7 @@ fcode_init_program(void)
|
||||
{
|
||||
/* If the payload is Fcode then we execute it immediately */
|
||||
ucell address;
|
||||
uint8_t fcode_header[8];
|
||||
|
||||
fword("load-base");
|
||||
address = POP();
|
||||
@@ -101,7 +103,7 @@ fcode_init_program(void)
|
||||
return;
|
||||
}
|
||||
|
||||
PUSH(address);
|
||||
PUSH(address + sizeof(fcode_header));
|
||||
PUSH(1);
|
||||
fword("byte-load");
|
||||
}
|
||||
|
||||
33
libopenbios/load.c
Normal file
33
libopenbios/load.c
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Creation Date: <2010/06/25 20:00:00 mcayland>
|
||||
* Time-stamp: <2010/06/25 20:00:00 mcayland>
|
||||
*
|
||||
* <load.c>
|
||||
*
|
||||
* C implementation of load
|
||||
*
|
||||
* 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
|
||||
* version 2
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "kernel/kernel.h"
|
||||
#include "libopenbios/bindings.h"
|
||||
#include "libopenbios/load.h"
|
||||
|
||||
#include "libopenbios/fcode_load.h"
|
||||
|
||||
|
||||
void load(ihandle_t dev)
|
||||
{
|
||||
/* Invoke the loaders on the specified device */
|
||||
|
||||
#ifdef CONFIG_LOADER_FCODE
|
||||
fcode_load(dev);
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -177,7 +177,7 @@ dlabel_load( __attribute__((unused)) dlabel_info_t *di )
|
||||
|
||||
xt = find_ih_method("load", di->part_ih);
|
||||
if (!xt) {
|
||||
forth_printf("load currently not implemented for /packages/disk-label\n");
|
||||
forth_printf("load currently not implemented for ihandle " FMT_ucellx "\n", di->part_ih);
|
||||
PUSH(0);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "libopenbios/bindings.h"
|
||||
#include "libopenbios/load.h"
|
||||
#include "mac-parts.h"
|
||||
#include "libc/byteorder.h"
|
||||
#include "libc/vsprintf.h"
|
||||
@@ -328,8 +329,8 @@ macparts_read(macparts_info_t *di )
|
||||
static void
|
||||
macparts_load( __attribute__((unused))macparts_info_t *di )
|
||||
{
|
||||
forth_printf("load currently not implemented for /packages/mac-parts\n");
|
||||
PUSH(0);
|
||||
/* Invoke the loader */
|
||||
load(my_self());
|
||||
}
|
||||
|
||||
NODE_METHODS( macparts ) = {
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "libopenbios/bindings.h"
|
||||
#include "libopenbios/load.h"
|
||||
#include "libc/byteorder.h"
|
||||
#include "libc/vsprintf.h"
|
||||
#include "packages.h"
|
||||
@@ -352,8 +353,8 @@ pcparts_read(pcparts_info_t *di )
|
||||
static void
|
||||
pcparts_load( __attribute__((unused))pcparts_info_t *di )
|
||||
{
|
||||
forth_printf("load currently not implemented for /packages/pc-parts\n");
|
||||
PUSH(0);
|
||||
/* Invoke the loader */
|
||||
load(my_self());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "libopenbios/bindings.h"
|
||||
#include "libopenbios/load.h"
|
||||
#include "libc/byteorder.h"
|
||||
#include "libc/vsprintf.h"
|
||||
#include "packages.h"
|
||||
@@ -284,8 +285,8 @@ sunparts_read(sunparts_info_t *di )
|
||||
static void
|
||||
sunparts_load( __attribute__((unused))sunparts_info_t *di )
|
||||
{
|
||||
forth_printf("load currently not implemented for /packages/sun-parts\n");
|
||||
PUSH(0);
|
||||
/* Invoke the loader */
|
||||
load(my_self());
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user