jmp_to_elf_entry

steven james pyro at linuxlabs.com
Sun May 4 06:40:01 CEST 2003


Greetings,


This message got more involved than I intended. I'd best preface it!
Most of the bolow message is potential policy in payloads. LinuxBIOS need
not (and probably should not) implement it, but will need to facillitate,
or at least accomodate it:

The fixups I'm now doing in bootselect seem to be working reasonably well,
but certainly have issues to be addressed. To start, the top of RAM works
well enough on the board I'm using, but that will have to be adjusted on a
system that actually uses an SMA framebuffer. Also, it would definatly
fail on a wierd system that has holes in memory near the top, but that
will be fixed in the real production code (as opposed to the quick and
dirty exploritory code I'm using now).

Currently, I'm doing the stack relocation with:

unsigned long int ramtop;
unsigned long int free_ramtop;

int _main(void) {
	lbmem = get_lbmem();

	DPRINTF("Got lbmem struct: %08x\n", (unsigned int) lbmem);

	ramtop = find_ramtop(lbmem);
	DPRINTF("Top of RAM = %08x\n", ramtop);

	__asm__ __volatile__(
		"movl %%ebp, %%eax\n"
		"subl %%esp, %%eax\n"
		"movl %0, %%esp\n" 
		"movl %0, %%ebp\n"
		"pushl %%ebp\n" 
		"subl %%eax, %%esp\n" :: "d" (ramtop));

	// reserve a stack
	free_ramtop = ramtop - 0x8000;

	DPRINTF("ramtop = %08x, free_ramtop = %08x\n", ramtop, free_ramtop);
	DPRINTF("Calling main\n");

	return(main());
}

In reality, if _main returns, it will surely crash. So, _main should call
main, then hard_reset. 

This can remain inside the payloads, by moving _main into libbaremetal and
checking for a setup signature before messing with the stack, or LinuxBIOS
itself can do the initial setup and have the payloads just cooperate. Note
that a payload that will not return can ignore the change other than
avoiding stack overwrite.

One goal is to have baremetal share as much of the code with LinuxBIOS as
possible.  Much of it simply uses the source directly in the tree, a few
source files (boot.c elfboot.c) are slightly modified copies from the
tree, and linuxbios.c (modified) from etherboot.

One good approach would be for LinuxBIOS to move the stack in whatever
function calls elfload. At that point, it will know as much as it ever
will about areas to avoid. With that, the mods to elfboot and boot.c can
be folded back in without incident. LinuxBIOS can handle return from the
payload by either calling hard_reset, or trying the next stream pointer
and calling hard_resset when it encounters a null pointer  (I note that
the linker scripts do support multiple streams, but the feature isn't used
now).

Moving on to memory allocation, as I see it, there are several possible
states for an address region:

1. reserved (non-existant, flash, or a device)
2. available (real memory)
3. in use, only wipe out if you will never return.
4. stack, only wipe out after making other arrangements and you will never
return.

Case 3 may either be hierarchical (removed before returning), or
persistant (consider a 'driver' payload that leaves function pointers
and some code behind in a table when it returns). I'm not sure where the
latter is going (or not), but it'd be nice to leave the option open.

I believe that the non-returning payloads out there now can ignore 3, and
already do the right thing for 4, but they would need to either understand
the additional flags in the memory table (to the extent that they realize 
that 3 and 4 are usable memory for them), or have 3 and 4 specified in
some other structure.

One simple approach is a system wide variable that holds the highest
address that isn't somehow spoken for, and make sure all case 3 and 4
memory allocations are made out of high RAM.

G'day,
sjames



On 3 May 2003, Eric W. Biederman wrote:

> steven james <pyro at linuxlabs.com> writes:
> 
> > 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.
> 
> That sounds correct.  It was there for completeness rather than a real
> need.  And I never did test it.
>  
> > 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.
> 
> I would not be surprised to learn that the returning to LinuxBIOS
> was not working.
> 
> For LinuxBIOS itself all we can do is call hard_reset like we do
> for the other weird cases.  But for the baremetal tool kit there
> we can definitely do something interesting.
> 
> I will have to look at what you are looking at stack wise but I certainly
> think we should have a stack that is out of the way as well, and we cannot
> have that in LinuxBIOS until we actually know our final memory
> size.   And that information is not know until late.
> 
> There is one glitch in the LinuxBIOS code.  After thinking and
> looking at things and see what works most reliably.  We should
> be passing the address of the parameter block with the standard
> C calling conventions (and on x86 this is on the stack).  I have
> modified etherboot to do this.  I have not gotten back to the
> LinuxBIOS code.
> 
> With respect to memory maps.  That is one piece of information that
> we should pass both ways.  Both in the LinuxBIOS table, and in
> the parameter block we pass to the loaded image.
> 
> This allows someone to find the real memory usage as well as to
> find what the bootloader thinks about the current situation.
> A memory map is something fundamental enough that the memory
> allocation will always be changing. 
> 
> I need to take my that specifies things about ELF booting and do
> another version.  But I have not gotten quite that far yet.
> 
> Eric
> 
> _______________________________________________
> Linuxbios mailing list
> Linuxbios at clustermatic.org
> http://www.clustermatic.org/mailman/listinfo/linuxbios
> 

-- 
-------------------------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
-----------------------------------------------------------------------





More information about the coreboot mailing list