Large fixed arrays in basic 'kernel'

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
-m32
Member
Member
Posts: 120
Joined: Thu Feb 21, 2008 5:59 am
Location: Ottawa, Canada

Large fixed arrays in basic 'kernel'

Post 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!
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Where do you set your stack pointer to? Are you sure your stack is big enough?
User avatar
-m32
Member
Member
Posts: 120
Joined: Thu Feb 21, 2008 5:59 am
Location: Ottawa, Canada

Post 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.
User avatar
zaleschiemilgabriel
Member
Member
Posts: 232
Joined: Mon Feb 04, 2008 3:58 am

Post 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)...
User avatar
-m32
Member
Member
Posts: 120
Joined: Thu Feb 21, 2008 5:59 am
Location: Ottawa, Canada

Post 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?
User avatar
zaleschiemilgabriel
Member
Member
Posts: 232
Joined: Mon Feb 04, 2008 3:58 am

Post by zaleschiemilgabriel »

Hey, the first thanks I got on this forum. :P You're welcome!
User avatar
-m32
Member
Member
Posts: 120
Joined: Thu Feb 21, 2008 5:59 am
Location: Ottawa, Canada

Post 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.. :)
Post Reply