[syslinux:elflink] Fix support for Linux kernel images with no protected mode code

syslinux-bot for Josh Triplett josh at joshtriplett.org
Mon Apr 8 00:45:10 PDT 2013


Commit-ID:  f16d2c170888fb416a7b376eb0a29dd3f7cced24
Gitweb:     http://www.syslinux.org/commit/f16d2c170888fb416a7b376eb0a29dd3f7cced24
Author:     Josh Triplett <josh at joshtriplett.org>
AuthorDate: Wed, 27 Mar 2013 14:50:37 -0700
Committer:  Matt Fleming <matt.fleming at intel.com>
CommitDate: Mon, 8 Apr 2013 08:41:38 +0100

Fix support for Linux kernel images with no protected mode code

Some kernel images use the Linux kernel boot protocol and header
structure, but do not actually have any protected-mode code.  For
instance, grub's 1024-byte lnxboot.img consists of 1024 real-mode bytes
and 0 protected-mode bytes; you can concatenate it with a full grub
core.img to produce a self-contained bootable kernel, but you can also
use it standalone as the kernel with the core.img loaded as an initrd.

syslinux 4 supports this, but it no longer works with syslinux 5: the
memmap functions do not correctly handle a request to work with a 0-byte
region.  With lnxboot.img, this would cause syslinux to bail because it
thinks it has no space at the 1M load location but cannot relocate
lnxboot.img.  (In bailing, it gives the confusing error message "Bad
file descriptor", not because that error actually occurred when
attempting to boot the kernel, but because errno has that value on entry
to syslinux_boot_linux and nothing clears or sets it.)

Fix the regression by handling the corner case of no protected-mode code
explicitly.

Signed-off-by: Josh Triplett <josh at joshtriplett.org>
Signed-off-by: Burt Triplett <burt at pbjtriplett.org>
Signed-off-by: Matt Fleming <matt.fleming at intel.com>

---
 com32/lib/syslinux/load_linux.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/com32/lib/syslinux/load_linux.c b/com32/lib/syslinux/load_linux.c
index 471d8a5..04a5210 100644
--- a/com32/lib/syslinux/load_linux.c
+++ b/com32/lib/syslinux/load_linux.c
@@ -324,7 +324,8 @@ int syslinux_boot_linux(void *kernel_buf, size_t kernel_size,
     /* Place the kernel in memory */
 
     /* First, find a suitable place for the protected-mode code */
-    if (syslinux_memmap_type(amap, prot_mode_base, prot_mode_size)
+    if (prot_mode_size &&
+	syslinux_memmap_type(amap, prot_mode_base, prot_mode_size)
 	!= SMT_FREE) {
 	const struct syslinux_memmap *mp;
 	if (!hdr.relocatable_kernel)
@@ -423,12 +424,15 @@ int syslinux_boot_linux(void *kernel_buf, size_t kernel_size,
     }
 
     /* Protected-mode code */
-    if (syslinux_add_movelist(&fraglist, prot_mode_base,
-			      (addr_t) kernel_buf + real_mode_size,
-			      prot_mode_size))
-	goto bail;
-    if (syslinux_add_memmap(&amap, prot_mode_base, prot_mode_size, SMT_ALLOC))
-	goto bail;
+    if (prot_mode_size) {
+	if (syslinux_add_movelist(&fraglist, prot_mode_base,
+				  (addr_t) kernel_buf + real_mode_size,
+				  prot_mode_size))
+	    goto bail;
+	if (syslinux_add_memmap(&amap, prot_mode_base, prot_mode_size,
+				SMT_ALLOC))
+	    goto bail;
+    }
 
     /* Figure out the size of the initramfs, and where to put it.
        We should put it at the highest possible address which is


More information about the Syslinux-commits mailing list