[syslinux] PATCH: Handle virtual entry point in mboot.c32
Matthew Iselin
matthew at theiselins.net
Thu Apr 2 17:09:42 PDT 2009
Hi,
This patch ensures that mboot.c32 will always jump to a physical address
when loading a Multiboot kernel.
Some kernels are linked with a virtual entry point and without this patch
these kernels are unbootable.
Hope this helps,
Matthew
--- a/com32/modules/mboot.c 2009-04-03 09:48:08.000000000 +1000
+++ b/com32/modules/mboot.c 2009-04-03 09:48:16.000000000 +1000
@@ -650,6 +650,13 @@ static size_t load_kernel(struct multibo
exit(1);
}
+ /* The real entry point is the actual physical location of the
code to jump to.
+ * This allows kernels with a virtual entry point address to
successfully run (if
+ * their startup code is position-independent). For instance, a
kernel whose
+ * entry point is at 0xFF400000 virtual, but 0x100000 physical
will be able to
+ * be booted because of this special handling. */
+ Elf32_Addr realEntry = ehdr->e_entry;
+
#ifdef DEBUG
printf("Using ELF header.\n");
#endif
@@ -682,6 +689,17 @@ static size_t load_kernel(struct multibo
/* Skip segments that don't take up any memory */
if (run_size == 0) continue;
+ /* If the entry point is within this program header, set
the real
+ * entry point to the correct physical address. See GRUB's
stage2
+ * (line 620) for a similar calculation. */
+ if(
+ (ehdr->e_entry >= phdr[i].p_vaddr)
+ &&
+ (ehdr->e_entry < (phdr[i].p_vaddr + run_size))
+ ) {
+ realEntry = (ehdr->e_entry + phdr[i].p_paddr) -
phdr[i].p_vaddr;
+ }
+
/* Place the segment where it wants to be */
run_addr = phdr[i].p_paddr;
place_kernel_section(run_addr, run_size);
@@ -753,7 +771,7 @@ static size_t load_kernel(struct multibo
}
/* Done! */
- return ehdr->e_entry;
+ return realEntry;
}
}
More information about the Syslinux
mailing list