[ipxe-devel] Request for syslinux com32r support.

Daniel Verkamp daniel at drv.nu
Thu Apr 28 03:56:17 UTC 2011


(Resending to list, sent to Shao only by accident...)

On Tue, Apr 26, 2011 at 8:36 PM, Miller, Shao
<shao.miller at yrdsb.edu.on.ca> wrote:
> Is there a problem with using iPXE -> PXELINUX?  They can certainly be
> packaged together.
>
> COMBOOT32 modules are "going away" in favour of ELF, and maybe even EFI
> modules after that.  This might be a waste of effort unless you have a
> strong case for it.
>
> Daniel Verkamp's original COMBOOT module support for gPXE was certainly
> great work and has come in handy.
>
> - Shao Miller
>
> -----Original Message-----
> From: ipxe-devel-bounces at lists.ipxe.org
> [mailto:ipxe-devel-bounces at lists.ipxe.org] On Behalf Of Andrew Stuart
> Sent: Tuesday, April 26, 2011 21:35
> To: ipxe-devel at ipxe.org
> Subject: [ipxe-devel] Request for syslinux com32r support.
>
> Are there any developers interested in getting syslinux com32r support
> added to ipxe?
>
> I'm interested in seeing if some $$ would motivate someone to get it
> done? I don't have a lot to throw at it, nor know how much effort would
> be required to get it done.
>
> Payment via paypal, The only requirement I have is that it is high
> quality so that it can be added to future builds of ipxe (which implies
> patch is open source)
>
> -Andrew

I do have a preliminary patch for COM32R that I put together recently,
but it's unfinished (see attached).

I don't have the time to finish this at the moment, but anyone else is
welcome to use it as a base for further work.

This patch just recognizes the new COM32R signature and loads them in
the same fixed location as regular COM32 modules. The new arguments to
the entry point are also bogus.  This shouldn't break any existing,
working COM32 modules, but most COM32R modules that do anything
interesting probably won't work yet.

Chaining to PXELINUX is probably the better option going forward.

-- Daniel
-------------- next part --------------
From 2bf3b1b9cb9c84b489fb20db59df588cca5e3a6a Mon Sep 17 00:00:00 2001
From: Daniel Verkamp <daniel at drv.nu>
Date: Fri, 1 Apr 2011 23:32:18 -0700
Subject: [PATCH] [comboot] Add basic COM32R support

The new self-relocating COM32R format from Syslinux 4.x is very similar
to the existing COM32 format, so recognize the COM32R signature and
add minimal support for its additional stack arguments.
---
 src/arch/i386/image/com32.c |   95 ++++++++++++++++++++++++++++++++-----------
 1 files changed, 71 insertions(+), 24 deletions(-)

diff --git a/src/arch/i386/image/com32.c b/src/arch/i386/image/com32.c
index d6e48eb..6dabf0f 100644
--- a/src/arch/i386/image/com32.c
+++ b/src/arch/i386/image/com32.c
@@ -93,37 +93,68 @@ static int com32_exec_loop ( struct image *image ) {
 		 */
 		unregister_image ( image );
 
+		/* Set up stack image to be copied to the real stack immediately
+		 * before calling the COM32 entry point.
+		 */
+		uint32_t stack_image[] =
+		{
+			/* Number of additional arguments (filled later) */
+			0,
+
+			/* Pointer to the command line arguments */
+			virt_to_phys ( image->cmdline ? image->cmdline : "" ),
+
+			/* Pointer to INT call helper function */
+			virt_to_phys ( com32_intcall_wrapper ),
+
+			/* Pointer to low memory bounce buffer */
+			COM32_BOUNCE_SEG << 4,
+
+			/* Size of low memory bounce buffer */
+			get_fbms() * 1024 - (COM32_BOUNCE_SEG << 4),
+
+			/* Pointer to FAR call helper function */
+			virt_to_phys ( com32_farcall_wrapper ),
+
+			/* Pointer to CDECL helper function */
+			virt_to_phys ( com32_cfarcall_wrapper ),
+
+			/* Amount of memory controlled by the core */
+			0, /* TODO */
+
+			/* Pointer to the filename of the com32 module */
+			virt_to_phys ( image->name ),
+
+			/* Pointer to protected-mode functions */
+			0, /* TODO */
+		};
+
+		/* Update number of arguments */
+		stack_image[0] = sizeof ( stack_image ) / 4 - 1;
+
 		__asm__ __volatile__ (
 			"sidt com32_internal_idtr\n\t"
-			"lidt com32_external_idtr\n\t"	       /* Set up IDT */
+			"lidt com32_external_idtr\n\t"         /* Set up IDT */
 			"movl %%esp, (com32_internal_esp)\n\t" /* Save internal virtual address space ESP */
 			"movl (com32_external_esp), %%esp\n\t" /* Switch to COM32 ESP (top of available memory) */
 			"call _virt_to_phys\n\t"               /* Switch to flat physical address space */
-			"sti\n\t"			       /* Enable interrupts */
-			"pushl %0\n\t"                         /* Pointer to CDECL helper function */
-			"pushl %1\n\t"                         /* Pointer to FAR call helper function */
-			"pushl %2\n\t"                         /* Size of low memory bounce buffer */
-			"pushl %3\n\t"                         /* Pointer to low memory bounce buffer */
-			"pushl %4\n\t"                         /* Pointer to INT call helper function */
-			"pushl %5\n\t"                         /* Pointer to the command line arguments */
-			"pushl $6\n\t"                         /* Number of additional arguments */
-			"call *%6\n\t"                         /* Execute image */
-			"cli\n\t"			       /* Disable interrupts */
-			"call _phys_to_virt\n\t"	       /* Switch back to internal virtual address space */
-			"lidt com32_internal_idtr\n\t"	       /* Switch back to internal IDT (for debugging) */
+			"subl %%ecx, %%esp\n\t"                /* Account for space used by stack image */
+			"movl %%esp, %%edi\n\t"                /* Point %edi at stack top */
+			"shrl $2, %%ecx\n\t"                   /* Make %ecx count in DWORDs */
+			"rep movsl\n\t"                        /* Copy from %esi (stack image) to %edi (top of stack) */
+			"sti\n\t"                              /* Enable interrupts */
+			"call *%0\n\t"                         /* Execute image */
+			"cli\n\t"                              /* Disable interrupts */
+			"call _phys_to_virt\n\t"               /* Switch back to internal virtual address space */
+			"lidt com32_internal_idtr\n\t"         /* Switch back to internal IDT (for debugging) */
 			"movl (com32_internal_esp), %%esp\n\t" /* Switch back to internal stack */
 		:
 		:
-			/* %0 */ "r" ( virt_to_phys ( com32_cfarcall_wrapper ) ),
-			/* %1 */ "r" ( virt_to_phys ( com32_farcall_wrapper ) ),
-			/* %2 */ "r" ( get_fbms() * 1024 - (COM32_BOUNCE_SEG << 4) ),
-			/* %3 */ "i" ( COM32_BOUNCE_SEG << 4 ),
-			/* %4 */ "r" ( virt_to_phys ( com32_intcall_wrapper ) ),
-			/* %5 */ "r" ( virt_to_phys ( image->cmdline ?
-						      image->cmdline : "" ) ),
-			/* %6 */ "r" ( COM32_START_PHYS )
+			/* %0 */ "r" ( COM32_START_PHYS ),
+			/* %1 */ "S" ( virt_to_phys ( stack_image ) ),  /* copy from %esi */
+			/* %2 */ "c" ( sizeof ( stack_image ) )         /* %ecx is size of stack image in bytes */
 		:
-			"memory" );
+			"edi", "memory" );
 		DBGC ( image, "COM32 %p: returned\n", image );
 		break;
 
@@ -161,7 +192,8 @@ static int com32_exec_loop ( struct image *image ) {
  */
 static int com32_identify ( struct image *image ) {
 	const char *ext;
-	static const uint8_t magic[] = { 0xB8, 0xFF, 0x4C, 0xCD, 0x21 };
+	static const uint8_t com32_magic[]  = { 0xB8, 0xFF, 0x4C, 0xCD, 0x21 };
+	static const uint8_t com32r_magic[] = { 0xB8, 0xFE, 0x4C, 0xCD, 0x21 };
 	uint8_t buf[5];
 	
 	if ( image->len >= 5 ) {
@@ -170,9 +202,21 @@ static int com32_identify ( struct image *image ) {
 		 * B8 FF 4C CD 21
 		 */
 		copy_from_user ( buf, image->data, 0, sizeof(buf) );
-		if ( ! memcmp ( buf, magic, sizeof(buf) ) ) {
+		if ( ! memcmp ( buf, com32_magic, sizeof(buf) ) ) {
 			DBGC ( image, "COM32 %p: found magic number\n",
 			       image );
+
+			return 0;
+		}
+
+		/* Check for COM32R magic number
+		 * mov eax,21cd4cfeh
+		 * B8 FE 4C CD 21
+		 */
+		if ( ! memcmp ( buf, com32r_magic, sizeof(buf) ) ) {
+			DBGC ( image, "COM32 %p: found COM32R magic number (self-relocating)\n",
+			       image );
+
 			return 0;
 		}
 	}
@@ -195,6 +239,9 @@ static int com32_identify ( struct image *image ) {
 		return -ENOEXEC;
 	}
 
+	DBGC ( image, "COM32 %p: assuming COM32 based on extension\n",
+	       image );
+
 	return 0;
 }
 
-- 
1.7.5.rc1



More information about the ipxe-devel mailing list