[syslinux] [PATCH] Fix recognition of keeppxe option

Gene Cumm gene.cumm at gmail.com
Sun Mar 5 14:39:42 PST 2017


On Fri, Jun 10, 2016 at 2:06 AM, Adam Goldman via Syslinux
<syslinux at zytor.com> wrote:
> 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:

Adam, how about https://github.com/geneC/syslinux/compare/keeppxe ?  I
changed to using strstr() and a uint16_t (to match the called
function)
-- 
-Gene

diff --git a/com32/elflink/ldlinux/kernel.c b/com32/elflink/ldlinux/kernel.c
index f3ba37f..942f97c 100644
--- a/com32/elflink/ldlinux/kernel.c
+++ b/com32/elflink/ldlinux/kernel.c
@@ -48,14 +48,6 @@ int new_linux_kernel(char *okernel, char *ocmdline)

     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;

diff --git a/com32/lib/syslinux/load_linux.c b/com32/lib/syslinux/load_linux.c
index 26c39c1..0edb771 100644
--- a/com32/lib/syslinux/load_linux.c
+++ b/com32/lib/syslinux/load_linux.c
@@ -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))
@@ -166,6 +167,7 @@ int bios_boot_linux(void *kernel_buf, size_t kernel_size,
     struct syslinux_memmap *amap = NULL;
     uint32_t memlimit = 0;
     uint16_t video_mode = 0;
+    uint16_t bootflags = 0;
     const char *arg;

     cmdline_size = strlen(cmdline) + 1;
@@ -200,6 +202,14 @@ int bios_boot_linux(void *kernel_buf, size_t kernel_size,
     }
     }

+    if (syslinux_filesystem() == SYSLINUX_FS_PXELINUX &&
+    strstr(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 +505,7 @@ int bios_boot_linux(void *kernel_buf, size_t kernel_size,
     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