On Tue, Jul 01, 2003 at 05:15:29PM -0600, Eric W. Biederman wrote:
> No. Etherboot gets the size part correct. It just only includes it
> once.
You are right.
> If you want to submit a patch to fix etherboot please go ahead.
> I would request that anything that fixes multiboot support also
> add the detection of the multiboot header so it can coexist with
> more sane loaders.
OK, the patch is attached.
This code is confirmed to give the same memory map as GRUB.
If Multiboot header is not found, it switches to ELFboot.
--
Takeshi
Index: arch/i386/core/multiboot_loader.c
===================================================================
RCS file: /cvsroot/etherboot/etherboot/etherboot-5.1/src/arch/i386/core/multiboot_loader.c,v
retrieving revision 1.2
diff -u -u -r1.2 multiboot_loader.c
--- arch/i386/core/multiboot_loader.c 20 Dec 2002 07:40:58 -0000 1.2
+++ arch/i386/core/multiboot_loader.c 2 Jul 2003 11:55:07 -0000
@@ -1,3 +1,8 @@
+/* Multiboot support
+ *
+ * 2003-07-02 mmap fix and header probe by SONE Takeshi
+ */
+
struct multiboot_mods {
unsigned mod_start;
unsigned mod_end;
@@ -5,6 +10,14 @@
unsigned reserved;
};
+struct multiboot_mmap {
+ unsigned int size;
+ unsigned int base_addr_low;
+ unsigned int base_addr_high;
+ unsigned int length_low;
+ unsigned int length_high;
+ unsigned int type;
+};
/* The structure of a Multiboot 0.6 parameter block. */
struct multiboot_info {
@@ -27,20 +40,52 @@
unsigned syms_addr;
unsigned syms_shndx;
unsigned mmap_length;
- struct e820entry *mmap_addr;
+ unsigned mmap_addr;
/* The structure actually ends here, so I might as well put
* the ugly e820 parameters here...
*/
- unsigned e820entry_size;
- struct e820entry mmap[E820MAX];
+ struct multiboot_mmap mmap[E820MAX];
+};
+
+/* Multiboot image header (minimal part) */
+struct multiboot_header {
+ unsigned int magic;
+#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
+ unsigned int flags;
+ unsigned int checksum;
};
+static struct multiboot_header *mbheader;
+
static struct multiboot_info mbinfo;
+static void multiboot_probe(unsigned char *data, int len)
+{
+ int offset;
+ struct multiboot_header *h;
+
+ /* Multiboot spec requires the header to be in first 8KB of the image */
+ if (len > 8192)
+ len = 8192;
+
+ for (offset = 0; offset < len; offset += 4) {
+ h = (struct multiboot_header *) (data + offset);
+ if (h->magic == MULTIBOOT_HEADER_MAGIC
+ && h->magic + h->flags + h->checksum == 0) {
+ printf("/Multiboot");
+ mbheader = h;
+ return;
+ }
+ }
+ mbheader = 0;
+}
+
static inline void multiboot_boot(unsigned long entry)
{
unsigned char cmdline[512], *c;
int i;
+ if (!mbheader)
+ return;
/* Etherboot limits the command line to the kernel name,
* default parameters and user prompted parameters. All of
* them are shorter than 256 bytes. As the kernel name and
@@ -68,11 +113,21 @@
mbinfo.memupper = meminfo.memsize;
mbinfo.bootdev = 0; /* not booted from disk */
mbinfo.cmdline = virt_to_phys(cmdline);
- mbinfo.e820entry_size = sizeof(struct e820entry);
- mbinfo.mmap_length =
- mbinfo.e820entry_size * meminfo.map_count;
- mbinfo.mmap_addr = mbinfo.mmap;
- memcpy(mbinfo.mmap, meminfo.map, mbinfo.mmap_length);
+ for (i = 0; i < (int) meminfo.map_count; i++) {
+ mbinfo.mmap[i].size = sizeof(struct multiboot_mmap)
+ - sizeof(unsigned int);
+ mbinfo.mmap[i].base_addr_low =
+ (unsigned int) meminfo.map[i].addr;
+ mbinfo.mmap[i].base_addr_high =
+ (unsigned int) (meminfo.map[i].addr >> 32);
+ mbinfo.mmap[i].length_low =
+ (unsigned int) meminfo.map[i].size;
+ mbinfo.mmap[i].length_high =
+ (unsigned int) (meminfo.map[i].size >> 32);
+ mbinfo.mmap[i].type = meminfo.map[i].type;
+ }
+ mbinfo.mmap_length = meminfo.map_count * sizeof(struct multiboot_mmap);
+ mbinfo.mmap_addr = virt_to_phys(mbinfo.mmap);
/* The Multiboot 0.6 spec requires all segment registers to be
* loaded with an unrestricted, writeable segment.
Index: core/elf_loader.c
===================================================================
RCS file: /cvsroot/etherboot/etherboot/etherboot-5.1/src/core/elf_loader.c,v
retrieving revision 1.3
diff -u -u -r1.3 elf_loader.c
--- core/elf_loader.c 21 Feb 2003 03:33:00 -0000 1.3
+++ core/elf_loader.c 2 Jul 2003 11:55:17 -0000
@@ -159,6 +159,7 @@
}
printf("(ELF");
elf_freebsd_probe();
+ multiboot_probe(data, len);
printf(")... ");
phdr_size = estate.e.elf32.e_phnum * estate.e.elf32.e_phentsize;
if (estate.e.elf32.e_phoff + phdr_size > len) {
Index: core/osloader.c
===================================================================
RCS file: /cvsroot/etherboot/etherboot/etherboot-5.1/src/core/osloader.c,v
retrieving revision 1.9
diff -u -u -r1.9 osloader.c
--- core/osloader.c 24 May 2003 14:13:30 -0000 1.9
+++ core/osloader.c 2 Jul 2003 11:55:17 -0000
@@ -68,6 +68,7 @@
#ifdef IMAGE_MULTIBOOT
#include "../arch/i386/core/multiboot_loader.c"
#else
+#define multiboot_probe(data, len) do {} while(0)
#define multiboot_boot(entry) do {} while(0)
#endif
|