[syslinux] [GIT PULL] elflink ldlinux

Matt Fleming matt at console-pimps.org
Wed May 25 03:52:06 PDT 2011


Hi,

These patches contain support for some features that are already in
Syslinux 4 but weren't working properly on the elflink branch. It's
another step closer to feature parity with Syslinux 4.

Having to jump through the comboot API for localboot support is less
than ideal and I'll eventually fix that, probably when we move a big
chunk of code from asm to C.

Also, there's a change to the hdt module that fixes the (currently
broken) build on the elflink branch - it's not really ldlinux specific.

The following changes since commit 5b351abcd550b9042a7f3212cb2ed0718af57312:

  load_env32 should not include menu.h (2011-04-27 14:27:35 -0700)

are available in the git repository at:
  git://git.zytor.com/users/mfleming/syslinux.git for-hpa/elflink/ldlinux

Matt Fleming (5):
      hdt: libmenu.a no longer exists
      ldlinux: Search in isolinux/ directory for config files
      ldlinux: Add localboot support
      ldlinux: Add support for Auxillary Data Vector
      ldlinux: Remove __constructor attribute

 com32/elflink/ldlinux/Makefile                     |    3 +-
 com32/elflink/ldlinux/adv.c                        |    8 ++-
 com32/{lib/syslinux => elflink/ldlinux}/advwrite.c |    0
 com32/elflink/ldlinux/execute.c                    |   17 +++--
 com32/elflink/ldlinux/ipappend.c                   |    2 +-
 com32/elflink/ldlinux/ldlinux.c                    |   44 ++++++++++++-
 com32/elflink/ldlinux/readconfig.c                 |    2 +-
 com32/{lib/syslinux => elflink/ldlinux}/setadv.c   |    0
 com32/hdt/Makefile                                 |    2 +-
 com32/lib/Makefile                                 |    2 -
 com32/lib/syslinux/adv.c                           |   49 --------------
 com32/lib/syslinux/getadv.c                        |   68 --------------------
 core/comboot.inc                                   |    8 ++
 13 files changed, 70 insertions(+), 135 deletions(-)
 rename com32/{lib/syslinux => elflink/ldlinux}/advwrite.c (100%)
 rename com32/{lib/syslinux => elflink/ldlinux}/setadv.c (100%)
 delete mode 100644 com32/lib/syslinux/adv.c
 delete mode 100644 com32/lib/syslinux/getadv.c

diff --git a/com32/elflink/ldlinux/Makefile b/com32/elflink/ldlinux/Makefile
index 318b3ac..32780c4 100644
--- a/com32/elflink/ldlinux/Makefile
+++ b/com32/elflink/ldlinux/Makefile
@@ -19,7 +19,8 @@ CFLAGS += -I$(topdir)/core/elflink -I$(topdir)/core/include
 all: ldlinux.c32 ldlinux_lnx.a
 
 ldlinux.c32 : ldlinux.o cli.o readconfig.o refstr.o colors.o getadv.o \
-		adv.o ipappend.o execute.o kernel.o get_key.o 
+		adv.o ipappend.o execute.o kernel.o get_key.o \
+		advwrite.o setadv.o
 	$(LD) $(LDFLAGS) -o $@ $^
 
 LNXLIBOBJS = get_key.lo
diff --git a/com32/elflink/ldlinux/adv.c b/com32/elflink/ldlinux/adv.c
index be38e89..7869547 100644
--- a/com32/elflink/ldlinux/adv.c
+++ b/com32/elflink/ldlinux/adv.c
@@ -33,15 +33,21 @@
 
 #include <syslinux/adv.h>
 #include <klibc/compiler.h>
+#include <inttypes.h>
 #include <com32.h>
 
 void *__syslinux_adv_ptr;
 size_t __syslinux_adv_size;
 
-void __constructor __syslinux_get_adv(void)
+extern void adv_init(void);
+void __syslinux_init(void)
 {
     static com32sys_t reg;
 
+    /* Initialize the ADV structure */
+    reg.eax.w[0] = 0x0025;
+    __intcall(0x22, &reg, NULL);
+
     reg.eax.w[0] = 0x001c;
     __intcall(0x22, &reg, &reg);
     __syslinux_adv_ptr = MK_PTR(reg.es, reg.ebx.w[0]);
diff --git a/com32/lib/syslinux/advwrite.c b/com32/elflink/ldlinux/advwrite.c
similarity index 100%
rename from com32/lib/syslinux/advwrite.c
rename to com32/elflink/ldlinux/advwrite.c
diff --git a/com32/elflink/ldlinux/execute.c b/com32/elflink/ldlinux/execute.c
index a00a5b1..635e327 100644
--- a/com32/elflink/ldlinux/execute.c
+++ b/com32/elflink/ldlinux/execute.c
@@ -134,7 +134,7 @@ void execute(const char *cmdline, enum kernel_type type)
 		argv[argc] = NULL;
 		module_load_dependencies(kernel, "modules.dep");
 		spawn_load(kernel, argc, argv);
-	} else if (type <= KT_KERNEL) {
+	} else if (type == KT_KERNEL) {
 		/* Need add one item for kernel load, as we don't use
 		* the assembly runkernel.inc any more */
 		new_linux_kernel(kernel, cmdline);
@@ -148,14 +148,15 @@ void execute(const char *cmdline, enum kernel_type type)
 		if (type == KT_LOCALBOOT) {
 			ireg.eax.w[0] = 0x0014;	/* Local boot */
 			ireg.edx.w[0] = strtoul(kernel, NULL, 0);
+		} else {
+			ireg.eax.w[0] = 0x0016;	/* Run kernel image */
+			ireg.esi.w[0] = OFFS(kernel);
+			ireg.ds = SEG(kernel);
+			ireg.ebx.w[0] = OFFS(args);
+			ireg.es = SEG(args);
+			ireg.edx.l = type - KT_KERNEL;
+			/* ireg.ecx.l    = 0; *//* We do ipappend "manually" */
 		}
-		ireg.eax.w[0] = 0x0016;	/* Run kernel image */
-		ireg.esi.w[0] = OFFS(kernel);
-		ireg.ds = SEG(kernel);
-		ireg.ebx.w[0] = OFFS(args);
-		ireg.es = SEG(args);
-		ireg.edx.l = type - KT_KERNEL;
-		/* ireg.ecx.l    = 0; *//* We do ipappend "manually" */
 
 		__intcall(0x22, &ireg, NULL);
 	}
diff --git a/com32/elflink/ldlinux/ipappend.c b/com32/elflink/ldlinux/ipappend.c
index bd00092..cbd02b1 100644
--- a/com32/elflink/ldlinux/ipappend.c
+++ b/com32/elflink/ldlinux/ipappend.c
@@ -38,7 +38,7 @@
 struct syslinux_ipappend_strings __syslinux_ipappend_strings;
 static const char *syslinux_ipappend_string_list[32];
 
-void __constructor __syslinux_get_ipappend_strings(void)
+void __syslinux_get_ipappend_strings(void)
 {
     static com32sys_t reg;
     int i;
diff --git a/com32/elflink/ldlinux/ldlinux.c b/com32/elflink/ldlinux/ldlinux.c
index 9ba1aeb..8b5fd30 100644
--- a/com32/elflink/ldlinux/ldlinux.c
+++ b/com32/elflink/ldlinux/ldlinux.c
@@ -7,6 +7,7 @@
 #include "com32.h"
 #include "menu.h"
 #include "config.h"
+#include "syslinux/adv.h"
 
 #include <sys/module.h>
 
@@ -27,8 +28,13 @@ static void load_kernel(const char *kernel)
 	/* Virtual kernel? */
 	me = find_label(kernel);
 	if (me) {
-		/* XXX we don't handle LOCALBOOT yet */
-		execute(me->cmdline, KT_KERNEL);
+		enum kernel_type type = KT_KERNEL;
+
+		/* cmdline contains type specifier */
+		if (me->cmdline[0] == '.')
+			type = KT_NONE;
+
+		execute(me->cmdline, type);
 		/* We shouldn't return */
 		goto bad_kernel;
 	}
@@ -98,11 +104,43 @@ static void enter_cmdline(void)
 
 int main(int argc, char **argv)
 {
+	com32sys_t ireg, oreg;
+	uint8_t *adv;
+	int count = 0;
+
 	openconsole(&dev_rawcon_r, &dev_ansiserial_w);
 
 	parse_configs(NULL);
 
-	/* TODO: ADV */
+	__syslinux_init();
+	adv = syslinux_getadv(ADV_BOOTONCE, &count);
+	if (adv && count) {
+		/*
+		 * We apparently have a boot-once set; clear it and
+		 * then execute the boot-once.
+		 */
+		uint8_t *src, *dst, *cmdline;
+		int i;
+
+		src = adv;
+		cmdline = dst = malloc(count + 1);
+		if (!dst) {
+			printf("Failed to allocate memory for ADV\n");
+			goto cmdline;
+		}
+
+		for (i = 0; i < count; i++)
+			*dst++ = *src++;
+		*dst = '\0';	/* Null-terminate */
+
+		/* Clear the boot-once data from the ADV */
+		if (!syslinux_setadv(ADV_BOOTONCE, 0, NULL))
+			syslinux_adv_write();
+
+		load_kernel(cmdline); /* Shouldn't return */
+		goto cmdline;
+	}
+
 	/* TODO: Check KbdFlags? */
 
 	if (forceprompt)
diff --git a/com32/elflink/ldlinux/readconfig.c b/com32/elflink/ldlinux/readconfig.c
index 441651e..8ded92a 100644
--- a/com32/elflink/ldlinux/readconfig.c
+++ b/com32/elflink/ldlinux/readconfig.c
@@ -1154,7 +1154,7 @@ static int parse_one_config(const char *filename)
 	if (f)
 		goto config_found;
 
-	f = fopen("isolinux.cfg", "r");
+	f = fopen("isolinux/isolinux.cfg", "r");
 	if (f)
 		goto config_found;
 
diff --git a/com32/lib/syslinux/setadv.c b/com32/elflink/ldlinux/setadv.c
similarity index 100%
rename from com32/lib/syslinux/setadv.c
rename to com32/elflink/ldlinux/setadv.c
diff --git a/com32/hdt/Makefile b/com32/hdt/Makefile
index 65bc1c6..934ad25 100644
--- a/com32/hdt/Makefile
+++ b/com32/hdt/Makefile
@@ -19,7 +19,7 @@ topdir = ../..
 MAKEDIR = $(topdir)/mk
 include $(MAKEDIR)/elf.mk
 
-LIBS      = ../cmenu/libmenu/libmenu.a ../libupload/libcom32upload.a
+LIBS      = ../libupload/libcom32upload.a
 CFLAGS    += -I$(com32)/cmenu/libmenu -I$(com32)
 
 MODULES	  = hdt.c32
diff --git a/com32/lib/Makefile b/com32/lib/Makefile
index 5d41d7d..10fb4de 100644
--- a/com32/lib/Makefile
+++ b/com32/lib/Makefile
@@ -50,8 +50,6 @@ LIBSYSLINUX_OBJS = \
 	syslinux/ipappend.o syslinux/dsinfo.o syslinux/version.o	\
 	syslinux/pxe_get_cached.o syslinux/pxe_get_nic.o		\
 	syslinux/pxe_dns.o						\
-	syslinux/adv.o syslinux/advwrite.o syslinux/getadv.o		\
-	syslinux/setadv.o						\
 	syslinux/video/fontquery.o syslinux/video/forcetext.o		\
 	syslinux/video/reportmode.o
 
diff --git a/com32/lib/syslinux/adv.c b/com32/lib/syslinux/adv.c
deleted file mode 100644
index be38e89..0000000
--- a/com32/lib/syslinux/adv.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/* ----------------------------------------------------------------------- *
- *
- *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
- *
- *   Permission is hereby granted, free of charge, to any person
- *   obtaining a copy of this software and associated documentation
- *   files (the "Software"), to deal in the Software without
- *   restriction, including without limitation the rights to use,
- *   copy, modify, merge, publish, distribute, sublicense, and/or
- *   sell copies of the Software, and to permit persons to whom
- *   the Software is furnished to do so, subject to the following
- *   conditions:
- *
- *   The above copyright notice and this permission notice shall
- *   be included in all copies or substantial portions of the Software.
- *
- *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *   OTHER DEALINGS IN THE SOFTWARE.
- *
- * ----------------------------------------------------------------------- */
-
-/*
- * syslinux/adv.c
- *
- * Access the syslinux auxilliary data vector
- */
-
-#include <syslinux/adv.h>
-#include <klibc/compiler.h>
-#include <com32.h>
-
-void *__syslinux_adv_ptr;
-size_t __syslinux_adv_size;
-
-void __constructor __syslinux_get_adv(void)
-{
-    static com32sys_t reg;
-
-    reg.eax.w[0] = 0x001c;
-    __intcall(0x22, &reg, &reg);
-    __syslinux_adv_ptr = MK_PTR(reg.es, reg.ebx.w[0]);
-    __syslinux_adv_size = reg.ecx.w[0];
-}
diff --git a/com32/lib/syslinux/getadv.c b/com32/lib/syslinux/getadv.c
deleted file mode 100644
index 5578313..0000000
--- a/com32/lib/syslinux/getadv.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/* ----------------------------------------------------------------------- *
- *
- *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
- *
- *   Permission is hereby granted, free of charge, to any person
- *   obtaining a copy of this software and associated documentation
- *   files (the "Software"), to deal in the Software without
- *   restriction, including without limitation the rights to use,
- *   copy, modify, merge, publish, distribute, sublicense, and/or
- *   sell copies of the Software, and to permit persons to whom
- *   the Software is furnished to do so, subject to the following
- *   conditions:
- *
- *   The above copyright notice and this permission notice shall
- *   be included in all copies or substantial portions of the Software.
- *
- *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *   OTHER DEALINGS IN THE SOFTWARE.
- *
- * ----------------------------------------------------------------------- */
-
-/*
- * syslinux/getadv.c
- *
- * Get a data item from the auxilliary data vector.  Returns a pointer
- * and sets *size on success; NULL on failure.
- */
-
-#include <syslinux/adv.h>
-#include <klibc/compiler.h>
-#include <inttypes.h>
-
-const void *syslinux_getadv(int tag, size_t * size)
-{
-    const uint8_t *p;
-    size_t left;
-
-    p = syslinux_adv_ptr();
-    left = syslinux_adv_size();
-
-    while (left >= 2) {
-	uint8_t ptag = *p++;
-	size_t plen = *p++;
-	left -= 2;
-
-	if (ptag == ADV_END)
-	    return NULL;	/* Not found */
-
-	if (left < plen)
-	    return NULL;	/* Item overrun */
-
-	if (ptag == tag) {
-	    *size = plen;
-	    return p;
-	}
-
-	p += plen;
-	left -= plen;
-    }
-
-    return NULL;
-}
diff --git a/core/comboot.inc b/core/comboot.inc
index d6f670c..b0e118a 100644
--- a/core/comboot.inc
+++ b/core/comboot.inc
@@ -915,6 +915,13 @@ comapi_shufraw:
 		mov ecx,P_ECX
 		jmp shuffle_and_boot_raw
 
+;
+; INT 22h AX=0025h	Initialize the ADV structure
+;
+comapi_initadv:
+		call adv_init
+		ret
+
 		section .data16
 
 %macro		int21 2
@@ -974,6 +981,7 @@ int22_table:
 		dw comapi_err		; 0022 close directory
 		dw comapi_shufsize	; 0023 query shuffler size
 		dw comapi_shufraw	; 0024 cleanup, shuffle and boot raw
+		dw comapi_initadv	; 0025 initialize adv structure
 int22_count	equ ($-int22_table)/2
 
 APIKeyWait	db 0




More information about the Syslinux mailing list