Page 1 of 1

Kernel leave problem !!!

Posted: Sun Apr 03, 2005 2:53 pm
by Silverhawk
Hi !
After the kernel 0xc0000000 linking episod and so on, I've a new problem that didn't exists when I was in identity mapping...

Now, I've the following things done :
- my small kernel is linked at 0xC0000000
- paging is enabled (the first 4Mb and the 4Mb from 0xC0000000 are mapped)
- Custom GDT is enabled
- I call a small C function from assembly to display on the screen...

Here is the part of asm code that call the C function :

Code: Select all

... ; just after paging, gdt are enabled

; // Jump to the kernel main routine.
mov ebx,[multiboot_info]
push ebx
jmp startKernel
sub esp,4
hlt

the C function code for test purpose is :

Code: Select all


#include <bootstrap/multiboot.h>

/* The C entry point of our operating system */
void startKernel(multiboot_info_t* multiboot_info)
{
  int i;
  char *video = (char*)0xb8000;
  for(i=0 ; i<80*25*2 ; i+=2)
  {
    video[i] = '1';
    video[i+1] = 1 << 4;
  }
  
  return;
}

Well, when I compile this and execute it, bochs crash with a 13rd exception...
I've thought it was because of a mispaging... but after disassembing the C function :

Code: Select all


0xc0001000 <startKernel+0>:     push   %ebp
0xc0001001 <startKernel+1>:     mov    %esp,%ebp
0xc0001003 <startKernel+3>:     sub    $0x8,%esp
0xc0001006 <startKernel+6>:     movl   $0xb8000,0xfffffff8(%ebp)
0xc000100d <startKernel+13>:    movl   $0x0,0xfffffffc(%ebp)
0xc0001014 <startKernel+20>:    cmpl   $0xf9f,0xfffffffc(%ebp)
0xc000101b <startKernel+27>:    jle    0xc000101f <startKernel+31>
0xc000101d <startKernel+29>:    jmp    0xc000103a <startKernel+58>
0xc000101f <startKernel+31>:    mov    0xfffffffc(%ebp),%eax
0xc0001022 <startKernel+34>:    add    0xfffffff8(%ebp),%eax
0xc0001025 <startKernel+37>:    movb   $0x31,(%eax)
0xc0001028 <startKernel+40>:    mov    0xfffffffc(%ebp),%eax
0xc000102b <startKernel+43>:    add    0xfffffff8(%ebp),%eax
0xc000102e <startKernel+46>:    inc    %eax
0xc000102f <startKernel+47>:    movb   $0x10,(%eax)
0xc0001032 <startKernel+50>:    lea    0xfffffffc(%ebp),%eax
0xc0001035 <startKernel+53>:    addl   $0x2,(%eax)
0xc0001038 <startKernel+56>:    jmp    0xc0001014 <startKernel+20>
0xc000103a <startKernel+58>:    leave
0xc000103b <startKernel+59>:    ret

It seems to have a "pop %ebp" missed by gcc !!!

It must be the cause of bochs' crash... by why ?

In fact, when I prevent the C function from returning, using an infinite loop, like this :

Code: Select all


#include <bootstrap/multiboot.h>

/* The C entry point of our operating system */
void startKernel(multiboot_info_t* multiboot_info)
{
  int i;
  char *video = (char*)0xb8000;
  for(i=0 ; i<80*25*2 ; i+=2)
  {
    video[i] = '1';
    video[i+1] = 1 << 4;
  }
  
  for (;;)
    continue;

  return;
}

It works fine ! But its really hugly...
Is anyone knows about this error ? What is the solution !

thanks guys !

Re:Kernel leave problem !!!

Posted: Sun Apr 03, 2005 3:12 pm
by durand
Hi,

In your assembler code stub, change the jump instruction to a call instruction:

Code: Select all

call startKernel
The jump instruction doesn't push a return address onto the stack. The call instruction does. So, startKernel won't return to the correct address.

Re:Kernel leave problem !!!

Posted: Sun Apr 03, 2005 3:17 pm
by durand
Also, the stack usually grows downward. So, in your assembler stub again, you chould change your "sub esp,4" to a "add esp,4".

A push will decrement esp by 4 bytes.
A pop will increment esp by 4 bytes.

... unless you've purposely done something funny and your stack grows upwards. (is that possible?) But if you haven't done something on purpose, then it should be an add. :)

Re:Kernel leave problem !!!

Posted: Sun Apr 03, 2005 10:52 pm
by proxy
also it is noted that you are NOT missing a pop%ebp, that is basically what leave does, restores the stack frame (it is symetric to enter which does something similar to: push %ebp; mov %esp,%ebp)

also you may want to note that while you do a call to a function in 0xc0000000 land, your stack is still in low memory so you will want to add 0xc0000000 to the stack (this will become an issue if you ever want to unmap that first meg)

proxy

Re:Kernel leave problem !!!

Posted: Mon Apr 04, 2005 11:17 am
by Silverhawk
That the proof it isn't efficient to code too late in the evening ! ;D

Thanks for your help !

Re:Kernel leave problem !!!

Posted: Mon Apr 04, 2005 11:21 am
by DruG5t0r3
thats what happens when you compile with gcc with -O0 (no optimisation)...-03 will yield code with the pop %ebp in it. (But sometimes it's hard to troubleshoot -O3 code with all those crazy optimisation tricks.