One of the primary reasons that issues with the quik bootloader were not
detected earlier was because arch/ppc/qemu/main.c has a separate code path
for forcing an old-world boot when -boot c is passed to QEMU.
This commit implements the bootcode loader as a core OpenBIOS loader which
enables old-world payloads such as quik to be executed using:
load hd:,%BOOT
go
Note that we also fix a bug in mac-parts.c to ensure that we don't try and
interpose a filesystem package when %BOOT is passed as a filename.
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland(a)ilande.co.uk>
CC: Alexander Graf <agraf(a)suse.de>
CC: Andreas Färber <afaerber(a)suse.de>
---
openbios-devel/config/examples/ppc_config.xml | 1 +
openbios-devel/forth/debugging/client.fs | 4 ++
openbios-devel/include/libopenbios/bootcode_load.h | 22 ++++++
openbios-devel/libopenbios/bootcode_load.c | 71 ++++++++++++++++++++
openbios-devel/libopenbios/build.xml | 1 +
openbios-devel/libopenbios/load.c | 13 ++++
openbios-devel/packages/mac-parts.c | 16 ++---
7 files changed, 119 insertions(+), 9 deletions(-)
create mode 100644 openbios-devel/include/libopenbios/bootcode_load.h
create mode 100644 openbios-devel/libopenbios/bootcode_load.c
diff --git a/openbios-devel/config/examples/ppc_config.xml b/openbios-devel/config/examples/ppc_config.xml
index ccb616d..5bb789f 100644
--- a/openbios-devel/config/examples/ppc_config.xml
+++ b/openbios-devel/config/examples/ppc_config.xml
@@ -26,6 +26,7 @@
<option name="CONFIG_VGA_DEPTH" type="integer" value="8"/>
<option name="CONFIG_LOADER_AOUT" type="boolean" value="false"/>
<option name="CONFIG_LOADER_BOOTINFO" type="boolean" value="true"/>
+ <option name="CONFIG_LOADER_BOOTCODE" type="boolean" value="true"/>
<option name="CONFIG_LOADER_ELF" type="boolean" value="true"/>
<option name="CONFIG_LOADER_FCODE" type="boolean" value="false"/>
<option name="CONFIG_LOADER_FORTH" type="boolean" value="false"/>
diff --git a/openbios-devel/forth/debugging/client.fs b/openbios-devel/forth/debugging/client.fs
index 24b1ec7..9da9b33 100644
--- a/openbios-devel/forth/debugging/client.fs
+++ b/openbios-devel/forth/debugging/client.fs
@@ -27,6 +27,9 @@ create saved-program-state saved-program-state.size allot
variable state-valid
0 state-valid !
+variable want-bootcode
+0 want-bootcode !
+
variable file-size
: !load-size file-size ! ;
@@ -44,6 +47,7 @@ variable file-size
5 constant aout
10 constant fcode
11 constant forth
+12 constant bootcode
: init-program ( -- )
diff --git a/openbios-devel/include/libopenbios/bootcode_load.h b/openbios-devel/include/libopenbios/bootcode_load.h
new file mode 100644
index 0000000..147783a
--- /dev/null
+++ b/openbios-devel/include/libopenbios/bootcode_load.h
@@ -0,0 +1,22 @@
+/*
+ * Creation Date: <2010/03/22 18:00:00 mcayland>
+ * Time-stamp: <2010/03/22 18:00:00 mcayland>
+ *
+ * <bootcode_load.h>
+ *
+ * Raw bootcode (%BOOT) loader
+ *
+ * Copyright (C) 2013 Mark Cave-Ayland (mark.cave-ayland(a)ilande.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_BOOTCODELOAD
+#define _H_BOOTCODELOAD
+
+extern int bootcode_load(ihandle_t dev);
+
+#endif /* _H__H_BOOTCODELOAD */
diff --git a/openbios-devel/libopenbios/bootcode_load.c b/openbios-devel/libopenbios/bootcode_load.c
new file mode 100644
index 0000000..3644997
--- /dev/null
+++ b/openbios-devel/libopenbios/bootcode_load.c
@@ -0,0 +1,71 @@
+/*
+ * Raw bootcode loader (CHRP/Apple %BOOT)
+ * Written by Mark Cave-Ayland 2013
+ */
+
+#include "config.h"
+#include "kernel/kernel.h"
+#include "libopenbios/bindings.h"
+#include "libopenbios/bootcode_load.h"
+#include "libc/diskio.h"
+#include "drivers/drivers.h"
+#define printf printk
+#define debug printk
+
+#define OLDWORLD_BOOTCODE_BASEADDR (0x3f4000)
+
+int
+bootcode_load(ihandle_t dev)
+{
+ int retval = -1, count = 0, fd;
+ unsigned long bootcode, loadbase, offset;
+
+ /* Mark the saved-program-state as invalid */
+ feval("0 state-valid !");
+
+ fd = open_ih(dev);
+ if (fd == -1) {
+ goto out;
+ }
+
+ /* Default to loading at load-base */
+ fword("load-base");
+ loadbase = POP();
+
+#ifdef CONFIG_PPC
+ /* However Old World Macs need to load to a different address */
+ if (is_oldworld()) {
+ loadbase = OLDWORLD_BOOTCODE_BASEADDR;
+ }
+#endif
+
+ bootcode = loadbase;
+ offset = 0;
+
+ while(1) {
+ if (seek_io(fd, offset) == -1)
+ break;
+ count = read_io(fd, (void *)bootcode, 512);
+ offset += count;
+ bootcode += count;
+ }
+
+ /* If we didn't read anything then exit */
+ if (!count) {
+ goto out;
+ }
+
+ /* Initialise saved-program-state */
+ PUSH(loadbase);
+ feval("saved-program-state >sps.entry !");
+ PUSH(offset);
+ feval("saved-program-state >sps.file-size !");
+ feval("bootcode saved-program-state >sps.file-type !");
+
+ feval("-1 state-valid !");
+
+out:
+ close_io(fd);
+ return retval;
+}
+
diff --git a/openbios-devel/libopenbios/build.xml b/openbios-devel/libopenbios/build.xml
index 04e3800..8c1fe3f 100644
--- a/openbios-devel/libopenbios/build.xml
+++ b/openbios-devel/libopenbios/build.xml
@@ -3,6 +3,7 @@
<library name="openbios" type="static" target="target">
<object source="aout_load.c" condition="LOADER_AOUT"/>
<object source="bindings.c"/>
+ <object source="bootcode_load.c" condition="LOADER_BOOTCODE"/>
<object source="bootinfo_load.c" condition="LOADER_BOOTINFO"/>
<object source="client.c"/>
<object source="console_common.c"/>
diff --git a/openbios-devel/libopenbios/load.c b/openbios-devel/libopenbios/load.c
index 2a2a7f9..1d50a82 100644
--- a/openbios-devel/libopenbios/load.c
+++ b/openbios-devel/libopenbios/load.c
@@ -36,6 +36,10 @@
#include "libopenbios/forth_load.h"
#endif
+#ifdef CONFIG_LOADER_BOOTCODE
+#include "libopenbios/bootcode_load.h"
+#endif
+
struct sys_info sys_info;
void *elf_boot_notes = NULL;
@@ -92,4 +96,13 @@ void load(ihandle_t dev)
}
#endif
+#ifdef CONFIG_LOADER_BOOTCODE
+ /* Check for a "raw" %BOOT bootcode payload */
+ feval("want-bootcode @");
+ valid = POP();
+ if (valid) {
+ bootcode_load(dev);
+ }
+#endif
+
}
diff --git a/openbios-devel/packages/mac-parts.c b/openbios-devel/packages/mac-parts.c
index 85d53f8..c29b554 100644
--- a/openbios-devel/packages/mac-parts.c
+++ b/openbios-devel/packages/mac-parts.c
@@ -89,8 +89,12 @@ macparts_open( macparts_info_t *di )
parnum = atol(parstr);
/* Detect if we are looking for the bootcode */
- if (strcmp(argstr, "%BOOT") == 0)
+ if (strcmp(argstr, "%BOOT") == 0) {
want_bootcode = 1;
+ feval("1 want-bootcode !");
+ } else {
+ feval("0 want-bootcode !");
+ }
}
DPRINTF("parstr: %s argstr: %s parnum: %d\n", parstr, argstr, parnum);
@@ -285,16 +289,10 @@ macparts_open( macparts_info_t *di )
set_property(chosen_ph, "bootpath", bootpath, strlen(bootpath) + 1);
}
-
- /* If the filename was %BOOT then it's not a real filename, so clear argstr before
- attempting interpose */
- if (want_bootcode) {
- argstr = strdup("");
- }
-
+
/* If we have been asked to open a particular file, interpose the filesystem package with
the passed filename as an argument */
- if (strlen(argstr)) {
+ if (!want_bootcode && strlen(argstr)) {
push_str( argstr );
PUSH_ph( ph );
fword("interpose");
--
1.7.10.4