jmp_to_elf_entry

steven james pyro at linuxlabs.com
Sat May 3 15:48:00 CEST 2003


Greetings,

Looks like I've trodden on an unused code path, and found a bug.
In arch/i386/boot/boot.c: jmp_to_elf_entry, the idea is to copy all of the
running code (linuxbios, or a baremetal payload) to a bounce buffer, jump
into the copy there,  copy the bounce buffer of the target elf into place,
and call it. Upon return, the process is reversed, so that (in
theory) jmp_to_elf_entry returns and further processing can happen.

For some reason, the lines that subtract the adjustment from EAX, then
jump to move execution back to the proper place was failing. I've patched
it in the copy kept in util/baremetal/lib so that instead, it loads the
eventual jmp target into ecx, then saves it away on the stack. 

I'm surely missing something here, but the original goes into space while
the simple save off is working. I suppose that's just because we've never
tried to return to LinuxBIOS from a payload before.

The baremetal version also skips adjusting ESP since I'm moving the stack
out of the way first.

Ignore the // debugging stuff, that was just to see where things were
going wrong (I'll be getting rid of that).

Eric, since you wrote that part, I wanted to run this by you before making
any changes in LinuxBIOS itself.

G'day,
sjames


-- 
-------------------------steven james, director of research, linux labs
... ........ ..... ....                    230 peachtree st nw ste 2701
the original linux labs                             atlanta.ga.us 30303
      -since 1995                              http://www.linuxlabs.com
                                   office 404.577.7747 fax 404.577.7743
-----------------------------------------------------------------------


-------------- next part --------------
--- ../../../src/arch/i386/boot/boot.c	Thu Oct 10 15:02:28 2002
+++ boot.c	Sat May  3 15:54:10 2003
@@ -67,6 +67,7 @@
 	
 }
 
+#if 1
 void jmp_to_elf_entry(void *entry, unsigned long buffer)
 {
 	extern unsigned char _ram_seg, _eram_seg;
@@ -121,15 +122,19 @@
 		"	movl	 8(%%esp), %%ecx\n\n"
 		"	shrl	$2, %%ecx\n\t"
 		"	rep	movsl\n\t"
-
+#ifdef MOVE_STACK
 		/* Adjust the stack pointer to point into the new linuxBIOS image */
 		"	addl	20(%%esp), %%esp\n\t"
+#endif
 		/* Adjust the instruction pointer to point into the new linuxBIOS image */
 		"	movl	$1f, %%eax\n\t"
 		"	addl	20(%%esp), %%eax\n\t"
+		"	movl	$2f, %%ecx\n\t"
 		"	jmp	*%%eax\n\t"
 		"1:	\n\t"
 
+
+		"	movl	%%ecx, 20(%%esp)\n\t"
 		/* Copy the linuxBIOS bounce buffer over linuxBIOS */
 		/* Move ``longs'' the linuxBIOS size is 4 byte aligned */
 		"	movl	16(%%esp), %%edi\n\t"
@@ -142,6 +147,10 @@
 		"	movl	$0x0E1FB007, %%eax\n\t"
 		"	movl	 0(%%esp), %%ebx\n\t"
 		"	call	*4(%%esp)\n\t"
+// debygging
+		"	mov $0x41, %%al\n\t"
+		"	mov $0x3f8, %%dx\n\t"
+		"	outb %%al, %%dx\n\t"
 
 		/* The loaded image returned? */
 		"	cli	\n\t"
@@ -155,15 +164,22 @@
 		"	movl	 8(%%esp), %%ecx\n\t"
 		"	shrl	$2, %%ecx\n\t"
 		"	rep	movsl\n\t"
-
+#ifdef MOVE_STACK
 		/* Adjust the stack pointer to point into the old linuxBIOS image */
 		"	subl	20(%%esp), %%esp\n\t"
+#endif
 
 		/* Adjust the instruction pointer to point into the old linuxBIOS image */
-		"	movl	$1f, %%eax\n\t"
-		"	subl	20(%%esp), %%eax\n\t"
+//		"	movl	$1f, %%eax\n\t"
+//		"	subl	20(%%esp), %%eax\n\t"
+		"	movl	20(%%esp), %%eax\n\t"
 		"	jmp	*%%eax\n\t"
-		"1:	\n\t"
+		"2:	\n\t"
+
+// debygging
+		"	mov $0x42, %%al\n\t"
+		"	mov $0x3f8, %%dx\n\t"
+		"	outb %%al, %%dx\n\t"
 
 		/* Drop the parameters I was passed */
 		"	addl	$24, %%esp\n\t"
@@ -177,6 +193,16 @@
 		"g" (lb_start), "g" (buffer), "g" (lb_size),
 		"g" (entry), "g"(adjusted_boot_notes)
 		);
+
+		printk("jmp_to_elf_entry returning\n");
 }
 
+#else
+void jmp_to_elf_entry(void *entry, unsigned long buffer)
+{
+	void (*newmain)() = entry;
 
+	newmain();
+	return;
+}
+#endif


More information about the coreboot mailing list