Page 1 of 1

Large fixed arrays in basic 'kernel'

Posted: Thu Feb 21, 2008 6:33 am
by -m32
Hello,

In an attempt to get a starter 'kernel' going, I have hit a bit of a snag (to me at least)...

My problem is with large fixed arrays declared at compile-time in C. Specifically when passing their pointer to a function.

for example:

Code: Select all

void foo(void *p);
void KernelMain() {
   char a[0x1000];  /* not that this is very big */

    /* if I boot with this call, then the system will reboot */
    foo(a);
}

void foo(void *p) {
   /* doesn't matter */
}
My boot loader merely reads two tracks off of a floppy disk (where the kernel is saved) loads it to 0x1000, sets cr0, creates a basic GDT with a DS of base 0 to limit FFFFF and a CS of base 0 to limit FFFFF.

Paging is not enabled.

The bootsector then jumps into the 'kernel' and continues execution there.

At this point the system reboots (does NOT occur in VirtualBox, Bochs, etc...)

If I make the array global, the reboot does not occur, presumably because it's not being put into the stack like the inline array.

I realize malloc would be a better way to acquire space, but malloc doesn't exist yet.

Can anyone explain to me why this is happening? I'd be nice to know how to fix it too :)


If you need to see my bootsector, it'll have to wait until I get home tonight ;)

Thanks for any help!

Posted: Thu Feb 21, 2008 6:45 am
by JamesM
Where do you set your stack pointer to? Are you sure your stack is big enough?

Posted: Thu Feb 21, 2008 7:04 am
by -m32
Hmmm, maybe I'm just dumb but I never set the stack pointer to anything, I assumed that it points to the 'top' of available memory on boot and thus didn't need to be set to anything in particular... I figured setting the ss to the code descriptor would be enough.

Thanks for the reply.

Posted: Thu Feb 21, 2008 8:05 am
by zaleschiemilgabriel
* The standard MBR sets SS to 0 and SP to 7C00h, but you should not rely on that.
* If you are writing your own MBR (if booting from a floppy) then SS and SP are undefined, so read on...
Once you switch to PM, you have to set a valid segment descriptor into SS and set ESP (or SP if you use 16 bit) to a large enough limit to compensate for your arrays and the extra space needed to call other functions. If you don't set SS and ESP correctly, the first time you call a function using the CALL instruction, a GPF is issued and the machine reboots. Emulators don't reboot in this case. Instead, they either give you an error message (Virtual PC does) or show some debugging info (Bochs)...

Posted: Thu Feb 21, 2008 8:49 am
by -m32
Thanks, I'm sure that's what the problem is. Don't know why I didn't think of it.. :)

I did set my ss correctly, but I guess the esp is pointing to 'too small an area by default. If it is a GPF I can't tell. In my 'actual' source code, I have an IDT loaded and it's supposed to hang on any exceptions but it just reboots anyway. I'm not sure why that happens, perhaps part of the IDT is getting overwritten with stack data?

Posted: Thu Feb 21, 2008 11:11 am
by zaleschiemilgabriel
Hey, the first thanks I got on this forum. :P You're welcome!

Posted: Thu Feb 21, 2008 6:31 pm
by -m32
Damn I'm an idiot :P

Not only was the esp pointing at who knows where, but of course I was actually loading the kernel at physical address 0x1000 (I meant to load it at 0x100000). That certainly didn't help :)

Setting esp to point to the end of a reserved block and loading the kernel at the 1MB mark fixed it.. :)