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