diff --git a/src/fw/coreboot.c b/src/fw/coreboot.c
index 7815de4..df940cb 100644
--- a/src/fw/coreboot.c
+++ b/src/fw/coreboot.c
@@ -17,6 +17,7 @@
 #include "stacks.h" // yield
 #include "string.h" // memset
 #include "util.h" // coreboot_preinit
+#include "multiboot.h"
 
 
 /****************************************************************
@@ -462,6 +463,67 @@ coreboot_cbfs_init(void)
     process_links_file();
 }
 
+static int
+extract_filename(char *dest, char *src, size_t lim)
+{
+  char *ptr;
+  for (ptr = src; *ptr; ptr++)
+    {
+      if (!(ptr == src || ptr[-1] == ' ' || ptr[-1] == '\t'))
+	continue;
+      /* memcmp stops early if it encounters \0 as it doesn't match name=.  */
+      if (memcmp(ptr, "name=", 5) == 0)
+	{
+	  int i;
+	  char *optr = dest;
+	  for (i = 0, ptr += 5; *ptr && *ptr != ' ' && i < lim; i++)
+	    *optr++ = *ptr++;
+	  *optr++ = '\0';
+	  return 1;
+	}
+    }
+  return 0;
+}
+
+void
+coreboot_multiboot_init(u32 mbptr)
+{
+  struct multiboot_info *mbi = (void *)mbptr;
+  dprintf (1, "mbptr=0x%x\n", mbptr);
+  if (mbptr == NO_MULTIBOOT)
+    return;
+  mbi = (void *)mbptr;
+  dprintf (1, "flags=0x%x, mods=0x%x, mods_c=%d\n", mbi->flags, mbi->mods_addr,
+	   mbi->mods_count);
+  if (!(mbi->flags & MULTIBOOT_INFO_MODS))
+    return;
+  int i;
+  struct multiboot_mod_list *mod = (void *)mbi->mods_addr;
+  for (i = 0; i < mbi->mods_count; i++) {
+    struct cbfs_romfile_s *cfile;
+    u8 *copy;
+    u32 len;
+    if (!mod[i].cmdline)
+      continue;
+    len = mod[i].mod_end - mod[i].mod_start;
+    cfile = malloc_tmp(sizeof(*cfile));
+    memset(cfile, 0, sizeof(*cfile));
+    dprintf (1, "module %s, size 0x%x\n", (char *)mod[i].cmdline, len);
+    if (!extract_filename(cfile->file.name, (char *)mod[i].cmdline, sizeof(cfile->file.name)))
+      {
+	free (cfile);
+	continue;
+      }
+    dprintf (1, "assigned file name <%s>\n", cfile->file.name);
+    cfile->file.size = cfile->rawsize = len;
+    copy = malloc_tmp (len);
+    memcpy(copy, (void *)mod[i].mod_start, len);
+    cfile->file.copy = cbfs_copyfile;
+    cfile->data = copy;
+    romfile_add(&cfile->file);
+  }
+}
+
 struct cbfs_payload_segment {
     u32 type;
     u32 compression;
diff --git a/src/fw/csm.c b/src/fw/csm.c
index 7cdb398..9382aa4 100644
--- a/src/fw/csm.c
+++ b/src/fw/csm.c
@@ -61,7 +61,7 @@ csm_return(struct bregs *regs)
 static void
 csm_maininit(struct bregs *regs)
 {
-    interface_init();
+    interface_init(NO_MULTIBOOT);
     pci_probe_devices();
 
     csm_compat_table.PnPInstallationCheckSegment = SEG_BIOS;
diff --git a/src/post.c b/src/post.c
index 9ea5620..5585340 100644
--- a/src/post.c
+++ b/src/post.c
@@ -108,7 +108,7 @@ bda_init(void)
 }
 
 void
-interface_init(void)
+interface_init(u32 mbptr)
 {
     // Running at new code address - do code relocation fixups
     malloc_init();
@@ -116,6 +116,7 @@ interface_init(void)
     // Setup romfile items.
     qemu_cfg_init();
     coreboot_cbfs_init();
+    coreboot_multiboot_init(mbptr);
 
     // Setup ivt/bda/ebda
     ivt_init();
@@ -208,10 +209,10 @@ startBoot(void)
 
 // Main setup code.
 static void
-maininit(void)
+maininit(u32 mbptr)
 {
     // Initialize internal interfaces.
-    interface_init();
+    interface_init(mbptr);
 
     // Setup platform devices.
     platform_hardware_setup();
@@ -302,7 +303,7 @@ reloc_preinit(void *f, void *arg)
 
 // Setup for code relocation and then relocate.
 void VISIBLE32INIT
-dopost(void)
+dopost(u32 mbptr)
 {
     // Detect ram and setup internal malloc.
     qemu_preinit();
@@ -310,14 +311,14 @@ dopost(void)
     malloc_preinit();
 
     // Relocate initialization code and call maininit().
-    reloc_preinit(maininit, NULL);
+    reloc_preinit(maininit, (void *) mbptr);
 }
 
 // Entry point for Power On Self Test (POST) - the BIOS initilization
 // phase.  This function makes the memory at 0xc0000-0xfffff
 // read/writable and then calls dopost().
 void VISIBLE32FLAT
-handle_post(void)
+handle_post(u32 mbptr)
 {
     if (!CONFIG_QEMU && !CONFIG_COREBOOT)
         return;
@@ -332,5 +333,5 @@ handle_post(void)
     make_bios_writable();
 
     // Now that memory is read/writable - start post process.
-    dopost();
+    dopost(mbptr);
 }
diff --git a/src/romlayout.S b/src/romlayout.S
index 93b6874..071f71b 100644
--- a/src/romlayout.S
+++ b/src/romlayout.S
@@ -372,6 +372,7 @@ entry_bios32:
         DECLFUNC entry_elf
         .code32
 entry_elf:
+        movl %eax, %ecx
         cli
         cld
         lidtl (BUILD_BIOS_ADDR + pmode_IDT_info)
@@ -383,6 +384,19 @@ entry_elf:
         movw %ax, %gs
         movw %ax, %ss
         movl $BUILD_STACK_ADDR, %esp
+        movl $0x2BADB002, %eax
+        cmpl %ecx, %eax
+        je  multiboot
+        xorl %ebx, %ebx
+        decl %ebx
+multiboot:
+	/* When compiled with -mregparm=1 or higher first argument is in
+	   %eax, otherwise it's on stack. Support both.
+	*/
+        movl  %ebx, %eax
+        pushl %ebx
+	/* Fake return address.  */
+        pushl %ebx
         ljmpl $SEG32_MODE32_CS, $_cfunc32flat_handle_post
         .code16
 
diff --git a/src/util.h b/src/util.h
index 704ae0a..e65f0ae 100644
--- a/src/util.h
+++ b/src/util.h
@@ -90,6 +90,7 @@ void coreboot_platform_setup(void);
 void cbfs_payload_setup(void);
 void coreboot_preinit(void);
 void coreboot_cbfs_init(void);
+void coreboot_multiboot_init(u32 mbptr);
 struct cb_header;
 void *find_cb_subtable(struct cb_header *cbh, u32 tag);
 struct cb_header *find_cb_table(void);
@@ -213,7 +214,8 @@ u16 get_pnp_offset(void);
 void pnp_init(void);
 
 // post.c
-void interface_init(void);
+#define NO_MULTIBOOT 0xffffffff
+void interface_init(u32 mbptr);
 void device_hardware_setup(void);
 void prepareboot(void);
 void startBoot(void);
_______________________________________________
SeaBIOS mailing list
[email protected]
http://www.seabios.org/mailman/listinfo/seabios

Reply via email to