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
diff --git a/arch/sparc32/boot.c b/arch/sparc32/boot.c
index a5cb841..5d3e46f 100644
--- a/arch/sparc32/boot.c
+++ b/arch/sparc32/boot.c
@@ -30,12 +30,16 @@
{
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 @@
#ifdef CONFIG_LOADER_FCODE
/* Fcode loader */
- fcode_load(path);
+ fcode_load(dev);
feval("state-valid @");
valid = POP();
if (valid)
@@ -75,6 +79,8 @@
goto start_image;
#endif
+ close_dev(dev);
+
return 0;
diff --git a/arch/sparc64/boot.c b/arch/sparc64/boot.c
index ba12a47..4a3a921 100644
--- a/arch/sparc64/boot.c
+++ b/arch/sparc64/boot.c
@@ -27,6 +27,10 @@
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 @@
#ifdef CONFIG_LOADER_FCODE
/* Fcode loader */
- fcode_load(path);
+ fcode_load(dev);
feval("state-valid @");
valid = POP();
if (valid)
@@ -67,6 +71,8 @@
goto start_image;
#endif
+ close_dev(dev);
+
return 0;
diff --git a/arch/x86/boot.c b/arch/x86/boot.c
index 6802069..81238c8 100644
--- a/arch/x86/boot.c
+++ b/arch/x86/boot.c
@@ -24,6 +24,10 @@
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 @@
#ifdef CONFIG_LOADER_FCODE
/* Fcode loader */
- fcode_load(path);
+ fcode_load(dev);
feval("state-valid @");
valid = POP();
if (valid)
@@ -64,6 +68,8 @@
goto start_image;
#endif
+ close_dev(dev);
+
return 0;
diff --git a/forth/admin/nvram.fs b/forth/admin/nvram.fs
index 58cd49d..6a29053 100644
--- a/forth/admin/nvram.fs
+++ b/forth/admin/nvram.fs
@@ -358,7 +358,7 @@
[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]
diff --git a/include/libopenbios/fcode_load.h b/include/libopenbios/fcode_load.h
index c2c341a..a84ac98 100644
--- a/include/libopenbios/fcode_load.h
+++ b/include/libopenbios/fcode_load.h
@@ -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 */
diff --git a/include/libopenbios/load.h b/include/libopenbios/load.h
new file mode 100644
index 0000000..2a4d97f
--- /dev/null
+++ b/include/libopenbios/load.h
@@ -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 */
diff --git a/libopenbios/build.xml b/libopenbios/build.xml
index dfe24a3..04e3800 100644
--- a/libopenbios/build.xml
+++ b/libopenbios/build.xml
@@ -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"/>
diff --git a/libopenbios/fcode_load.c b/libopenbios/fcode_load.c
index 48e34f1..9e582b2 100644
--- a/libopenbios/fcode_load.c
+++ b/libopenbios/fcode_load.c
@@ -24,7 +24,7 @@
}
int
-fcode_load(const char *filename)
+fcode_load(ihandle_t dev)
{
int retval = -1;
uint8_t fcode_header[8];
@@ -34,7 +34,7 @@
/* 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 @@
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 @@
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 @@
{
/* 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 @@
return;
}
- PUSH(address);
+ PUSH(address + sizeof(fcode_header));
PUSH(1);
fword("byte-load");
}
diff --git a/libopenbios/load.c b/libopenbios/load.c
new file mode 100644
index 0000000..b512893
--- /dev/null
+++ b/libopenbios/load.c
@@ -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
+
+}
diff --git a/packages/disk-label.c b/packages/disk-label.c
index 09c0920..2a7dd94 100644
--- a/packages/disk-label.c
+++ b/packages/disk-label.c
@@ -177,7 +177,7 @@
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;
}
diff --git a/packages/mac-parts.c b/packages/mac-parts.c
index d11a4fa..1dddefd 100644
--- a/packages/mac-parts.c
+++ b/packages/mac-parts.c
@@ -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 @@
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 ) = {
diff --git a/packages/pc-parts.c b/packages/pc-parts.c
index 93b5d9e..21dcb66 100644
--- a/packages/pc-parts.c
+++ b/packages/pc-parts.c
@@ -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 @@
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());
}
diff --git a/packages/sun-parts.c b/packages/sun-parts.c
index 7562817..f039ee7 100644
--- a/packages/sun-parts.c
+++ b/packages/sun-parts.c
@@ -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 @@
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());
}