Hi,
attached is the multiple payload support originally by Uwe Hermann. I am
lazy to attach Uwe's Kconfig and Makefile changes, get them at:
http://www.linuxbios.org/pipermail/linuxbios/2007-August/023728.html
To be less obtrusive, created a run_payload function which does the
logic already present. This function will be called in every iteration
(normal/payload0..9 and as a last resolt normal/payload).
Added pusha/popa around payload entry points. Not a big safety otoh.
In no means is this mature enough for a commit.
--
Alex
Index: arch/x86/stage1.c
===================================================================
--- arch/x86/stage1.c (revision 494)
+++ arch/x86/stage1.c (working copy)
@@ -68,6 +68,49 @@
return -1;
}
+static inline int run_payload(struct mem_file *archive, char *name, struct lb_memory *mem)
+{
+ int ret, i;
+ struct mem_file result;
+ void *entry;
+
+ printk(BIOS_SPEW, "Try payload: %s\n", name);
+
+ ret = find_file(archive, name, &result);
+ if (! ret) {
+ __asm__ __volatile__ ("pusha");
+ ret = legacy(archive, name, (void *)UNCOMPRESS_AREA, mem);
+ __asm__ __volatile__ ("popa");
+ return ret;
+ }
+
+ /* new style lar boot. Install all the files in memory.
+ * By convention we take the entry point from the first
+ * one. Look for a cmdline as well.
+ */
+ for(i = 0, entry = (void *)0; ;i++) {
+ char filename[64];
+ void *newentry;
+ sprintf(filename, "%s/segment%d", name, i);
+ archive->len = *(u32 *)0xfffffff4;
+ archive->start =(void *)(0UL-archive->len);
+ newentry = load_file(archive, filename);
+ printk(BIOS_SPEW, "newentry is %p\n", newentry);
+ if (newentry == (void *)-1)
+ break;
+ if (! entry)
+ entry = newentry;
+ }
+ printk(BIOS_SPEW, "all loaded, entry %p\n", entry);
+ if (entry) {
+ __asm__ __volatile__ ("pusha");
+ run_address(entry);
+ __asm__ __volatile__ ("popa");
+ return 1;
+ }
+ return -1;
+}
+
/*
* This function is called from assembler code whith its argument on the
* stack. Force the compiler to generate always correct code for this case.
@@ -75,10 +118,10 @@
void __attribute__((stdcall)) stage1_main(u32 bist)
{
int ret;
- struct mem_file archive, result;
+ struct mem_file archive;
int elfboot_mem(struct lb_memory *mem, void *where, int size);
- void *entry;
int i;
+ char filename[40];
/* we can't statically init this hack. */
unsigned char faker[64];
@@ -165,32 +208,16 @@
printk(BIOS_DEBUG, "Stage2 code done.\n");
- ret = find_file(&archive, "normal/payload", &result);
- if (! ret)
- legacy(&archive, "normal/payload", (void *)UNCOMPRESS_AREA, mem);
+ #define MAX_PAYLOADS 10
+ for (i = 0; i < MAX_PAYLOADS; i++) {
+ sprintf((char *)&filename, "normal/payload%d", i);
+ run_payload(&archive, (char *)&filename, mem);
+ }
+ /* Fallback to old normal/payload */
+ sprintf((char *)&filename, "normal/payload");
+ run_payload(&archive, (char *)&filename, mem);
- /* new style lar boot. Install all the files in memory.
- * By convention we take the entry point from the first
- * one. Look for a cmdline as well.
- */
- for(i = 0, entry = (void *)0; ;i++) {
- char filename[64];
- void *newentry;
- sprintf(filename, "normal/payload/segment%d", i);
- archive.len = *(u32 *)0xfffffff4;
- archive.start =(void *)(0UL-archive.len);
- newentry = load_file(&archive, filename);
- printk(BIOS_SPEW, "newentry is %p\n", newentry);
- if (newentry == (void *)-1)
- break;
- if (! entry)
- entry = newentry;
- }
- printk(BIOS_SPEW, "all loaded, entry %p\n", entry);
- if (entry)
- run_address(entry);
-
die("FATAL: No usable payload found.\n");
die ("FATAL: Last stage returned to LinuxBIOS.\n");
--
linuxbios mailing list
[email protected]
http://www.linuxbios.org/mailman/listinfo/linuxbios