[Etherboot-developers] Adding real-mode stack for prot_to_real
Brought to you by:
marty_connor,
stefanhajnoczi
|
From: Marc S. <el...@bu...> - 2002-09-21 04:17:37
|
On Fri, Sep 20, 2002 at 05:12:04PM -0600, Eric W Biederman wrote: > I have a confirmation for you. mknbi fails to setup it's own stack > and then behaves badly if etherboot doesn't give it a stack. > > I have triggered this bug in the development version by relocating > etherboot. > > If you have the time to change mknbi to setup it's own stack 1K should > be sufficient, it would be appreciated. > > The problem triggers in prot_to_real && real_to_prot. > If I understand it correctly, the problem is that the stack etherboot uses is greater than 64KiB away from the base address of mknbi. So, when prot_to_real substracts $RELOC from the %esp and installs the real-mode %ss, the stack has moved and is probably trouncing something interesting. Now we could make real-mode %ss behave and leave the stack where it is, or we could setup a real-mode stack for the benefit of BIOS calls. I've made a patch that I expect would work, but it doesn't. This is against mknbi-1.2-7. The behavior is a hard crash before I see anything from first32.c. I've put the real_stack in .code32 and in .data with no change in behavior. The odd thing is that if I only change the stack pointer to 0x00090000 before calling first() then I'll see the logon messages. It must be something simple that I'm not noticing. Ideas? BTW, I am aware that this won't work when we start in real-mode and first to protected mode first. I think all we need to do is push an initial 32 bit stack pointer before the first call to real_to_prot and all should be good. ============================================================ diff -u -r ../mknbi-1.2.7-original/start32.S ../mknbi-1.2.7/start32.S --- ../mknbi-1.2.7-original/start32.S 2002-03-04 04:44:53.000000000 -0800 +++ ../mknbi-1.2.7/start32.S 2002-09-20 21:07:54.000000000 -0700 @@ -350,6 +350,7 @@ movl %eax,%es movl %eax,%ss addl $RELOC,%esp /* Fix up stack pointer */ + popl %esp /* Restore 32 bit stack */ xorl %eax,%eax movl %eax,%fs movl %eax,%gs @@ -367,6 +368,10 @@ popl %eax subl $RELOC,%eax /* Adjust return address */ pushl %eax + movl %esp, %edx + lea real_stack, %eax + movl %eax, %esp + pushl %edx /* Save the 32 bit stack pointer */ subl $RELOC,%esp /* Adjust stack pointer */ #ifdef GAS291 ljmp $REAL_CODE_SEG,$1f-RELOC /* jump to a 16 bit segment */ @@ -437,9 +442,15 @@ /* Other variables */ #ifdef FIRST32PM +.global initsp initsp: .long 0 #else +.global initsp initss: .word 0 initsp: .word 0 days: .long 0 #endif + +.data +real_stack_end: .fill 1024,1,0 /* Real-mode only stack */ +real_stack: |