[syslinux] [PATCH] Fix recognition of keeppxe option

Adam Goldman adamg at pobox.com
Thu Jun 9 23:06:16 PDT 2016


PXELINUX has stopped recognizing the keeppxe option on the kernel 
command line. Here is a patch to make it work again.

With COM32, it is no longer possible to use preprocessor directives to 
determine the SYSLINUX variant. The code inside the #if will never be 
compiled. So, I changed it to use syslinux_filesystem() to determine the 
variant. Also, I moved the relevant code from 
kernel.c:new_linux_kernel() to load_linux.c:bios_boot_linux() because 
there is no convenient way in new_linux_kernel() to control the boot 
flags value.

In basic testing, keeppxe seems to work with the patch applied.


--- syslinux-6.04-pre1.orig/com32/elflink/ldlinux/kernel.c	2016-03-01 21:06:02.000000000 -0800
+++ syslinux-6.04-pre1/com32/elflink/ldlinux/kernel.c	2016-06-08 20:08:43.000000000 -0700
@@ -48,14 +48,6 @@ int new_linux_kernel(char *okernel, char
 
 	sprintf(cmdline, "BOOT_IMAGE=%s %s", kernel_name, args);
 
-	/* "keeppxe" handling */
-#if IS_PXELINUX
-	extern char KeepPXE;
-
-	if (strstr(cmdline, "keeppxe"))
-		KeepPXE |= 1;
-#endif
-
 	if (strstr(cmdline, "quiet"))
 		opt_quiet = true;
 
--- syslinux-6.04-pre1.orig/com32/lib/syslinux/load_linux.c	2016-03-01 21:06:02.000000000 -0800
+++ syslinux-6.04-pre1/com32/lib/syslinux/load_linux.c	2016-06-08 20:08:48.000000000 -0700
@@ -48,6 +48,7 @@
 #include <syslinux/movebits.h>
 #include <syslinux/firmware.h>
 #include <syslinux/video.h>
+#include <syslinux/config.h>
 
 #define BOOT_MAGIC 0xAA55
 #define LINUX_MAGIC ('H' + ('d' << 8) + ('r' << 16) + ('S' << 24))
@@ -59,8 +60,10 @@
 
 /* 
  * Find the last instance of a particular command line argument
- * (which should include the final =; do not use for boolean arguments)
+ * (which should include the final = for non-boolean arguments)
+ * Returns NULL if there is no match.
  * Note: the resulting string is typically not null-terminated.
+ * For boolean arguments, the returned pointer is valid but meaningless.
  */
 static const char *find_argument(const char *cmdline, const char *argument)
 {
@@ -166,6 +169,7 @@ int bios_boot_linux(void *kernel_buf, si
     struct syslinux_memmap *amap = NULL;
     uint32_t memlimit = 0;
     uint16_t video_mode = 0;
+    uint8_t bootflags = 0;
     const char *arg;
 
     cmdline_size = strlen(cmdline) + 1;
@@ -200,6 +204,14 @@ int bios_boot_linux(void *kernel_buf, si
 	}
     }
 
+    if (syslinux_filesystem() == SYSLINUX_FS_PXELINUX &&
+        find_argument(cmdline, "keeppxe")) {
+	extern __weak char KeepPXE;
+
+	KeepPXE = 1;		/* for pxelinux_scan_memory */
+	bootflags = 3;		/* for unload_pxe */
+    }
+
     /* Copy the header into private storage */
     /* Use whdr to modify the actual kernel header */
     memcpy(&hdr, kernel_buf, sizeof hdr);
@@ -495,7 +507,7 @@ int bios_boot_linux(void *kernel_buf, si
 	dprintf("*** vga=current, not calling syslinux_force_text_mode()...\n");
     }
 
-    syslinux_shuffle_boot_rm(fraglist, mmap, 0, &regs);
+    syslinux_shuffle_boot_rm(fraglist, mmap, bootflags, &regs);
     dprintf("shuffle_boot_rm failed\n");
 
 bail:


More information about the Syslinux mailing list