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@ilande.co.uk CC: Alexander Graf agraf@suse.de CC: Andreas Färber afaerber@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@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");