[Etherboot-developers] mknbi mkelf -1.9 stack problem.
Brought to you by:
marty_connor,
stefanhajnoczi
|
From: Eric W B. <ebi...@ln...> - 2002-09-10 04:03:37
|
Problem: mknbi && mkelf assume they will be given a stack pointer that can be accessed with RELOC as their %ss segment base address. mknbi handles this better as it calls _real_to_prot before calling _prot_to_real. With the _real_to_prot call first the stack pointer is mangled into something that works when etherboot runs at an unexpected address. The 32bit entry code does much less mangling of the stack pointer and breaks more visibly. When 5.1.2+ runs at unexpected address, both code bases break to some degree. I believe this is the primary reason why mkelf fails under 5.1.2+. Ken does this sound correct? If so when I have a moment I will add the code to switch to a private internal stack, so this issue will go away, unless someone beats me to it :) If I have a couple of more seconds I will merge in the mkelfImage support for working in even more arbitrary conditions. Eric /************************************************************************** _PROT_TO_REAL - Go from Protected Mode to REAL Mode **************************************************************************/ .globl _prot_to_real _prot_to_real: .code32 popl %eax subl $RELOC,%eax /* Adjust return address */ pushl %eax subl $RELOC,%esp /* Adjust stack pointer */ #ifdef GAS291 ljmp $REAL_CODE_SEG,$1f-RELOC /* jump to a 16 bit segment */ #else ljmp $REAL_CODE_SEG,$1f-_start /* jump to a 16 bit segment */ #endif /* GAS291 */ 1: .code16 movw $REAL_DATA_SEG,%ax movw %ax,%ds movw %ax,%ss movw %ax,%es movw %ax,%fs movw %ax,%gs /* clear the PE bit of CR0 */ movl %cr0,%eax andl $0!CR0_PE,%eax movl %eax,%cr0 /* make intersegment jmp to flush the processor pipeline * and reload %cs:%eip (to clear upper 16 bits of %eip). */ DATA32 ljmp $(RELOC)>>4,$2f-_start 2: /* we are in real mode now * set up the real mode segment registers : %ds, $ss, %es */ movw %cs,%ax movw %ax,%ds movw %ax,%es movw %ax,%ss sti DATA32 ret /* There is a 32 bit return address on the stack */ .code32 |