GDT Problem

If you are new to OS Development, plan on spending some time here first before going into the other forums.

Moderator:Moderators

Post Reply
oib111
Posts:38
Joined:Sat Aug 29, 2009 6:44 am
GDT Problem

Post by oib111 » Wed Sep 23, 2009 2:18 am

Ever since I put in code for the GDT I've had problems. Eventually I decided, temporarily, it'd just be easier to use the GDT setup by the bootloader. But now I'm coming towards the point where having a GDT is necessary, but I just don't know what's going on. I tried using the GDT code from the demo's but that didn't work either. That lead me to believe that perhaps the IDT was the problem, except everything is fine if I just use the bootloader's GDT, so I ruled out the IDT as the source of the problem. At this point, I'm thinking perhaps it's my gdt_flush() function:

Code: Select all

void gdt_flush() {
	#ifdef _MSC_VER
		_asm lgdt[gp]
	#endif
}
I don't really see anything wrong with that though :?

Andyhhp
Moderator
Posts:387
Joined:Tue Oct 23, 2007 10:05 am
Location:127.0.0.1
Contact:

Re: GDT Problem

Post by Andyhhp » Wed Sep 23, 2009 10:09 am

can you post all related code again please?
Image

oib111
Posts:38
Joined:Sat Aug 29, 2009 6:44 am

Re: GDT Problem

Post by oib111 » Wed Sep 23, 2009 2:26 pm

Ok.

from gdt.h

Code: Select all

// gdt entry structure
struct gdt_entry
{
    unsigned short limit_low;
    unsigned short base_low;
    unsigned char base_middle;
    unsigned char access;
    unsigned char granularity;
    unsigned char base_high;
};

// pointer to gdt (needed for lgdt instruction)
struct gdt_ptr
{
    unsigned short limit;
    unsigned int base;
};
from gdt.c

Code: Select all

// define three entries (NULL entry, code descriptor, data descriptor)
struct gdt_entry gdt[3];
struct gdt_ptr gp;

// this will load our gdt
void gdt_flush() {
	#ifdef _MSC_VER
		_asm lgdt[gp]
	#endif
}

void gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran) {
	gdt[num].base_low = (base & 0xFFFF);
    gdt[num].base_middle = ((base >> 16) & 0xFF);
    gdt[num].base_high = ((base >> 24) & 0xFF);

    gdt[num].limit_low = (limit & 0xFFFF);
    gdt[num].granularity = ((limit >> 16) & 0x0F);

    gdt[num].granularity |= (gran & 0xF0);
    gdt[num].access = access;
}

void gdt_install() {
	unsigned short csval, dsval, ssval, esval, fsval, gsval;
	gp.limit = (sizeof(struct gdt_entry) * 3) - 1;
	gp.base = gdt;
	 
	gdt_set_gate(0, 0, 0, 0, 0);
	// access 0x1A = 00011010 (bit 47-40)
	// granularity 0xCF = 11001111 (bit 55-48)
	gdt_set_gate(1, 0, 0xFFFFF, 0x1A, 0xCF);
	// access 0x12 = 00010010 (bit 47-40)
	// granularity 0xCF = 11001111 (bit 55-48)
	gdt_set_gate(2, 0, 0xFFFFF, 0x12, 0xCF);

	// load our GDT
	 
	gdt_flush();
}

User avatar
Mike
Site Admin
Posts:465
Joined:Sat Oct 20, 2007 7:58 pm
Contact:

Re: GDT Problem

Post by Mike » Wed Sep 23, 2009 10:31 pm

Hello,

Are the structures in gdt.h byte aligned?
Lead Programmer for BrokenThorn Entertainment, Co.
Website: http://www.brokenthorn.com
Email: webmaster@brokenthorn.com

oib111
Posts:38
Joined:Sat Aug 29, 2009 6:44 am

Re: GDT Problem

Post by oib111 » Wed Sep 23, 2009 10:46 pm

Yeah.

EDIT:

Fixed it...set the present bit in the GDT entries...not sure why that's a problem though. The tutorial describes that bit as only being used in Virtual Memory and just to ignore it and set it to 0. Oh well. Although, I'm having a problem with the memory maps, if anyone could take a look at that thread :)

Andyhhp
Moderator
Posts:387
Joined:Tue Oct 23, 2007 10:05 am
Location:127.0.0.1
Contact:

Re: GDT Problem

Post by Andyhhp » Thu Sep 24, 2009 12:41 pm

Hmm - the present bit tells the CPU whether the desctiptor is to be used or not. Can you find where in the tutorial it says to leave the present bit as 0?

~Andrew
Image

oib111
Posts:38
Joined:Sat Aug 29, 2009 6:44 am

Re: GDT Problem

Post by oib111 » Thu Sep 24, 2009 2:11 pm

Bit 7 (Bit 47 in GDT): Used to indicate the segment is in memory (Used with virtual memory). Set to zero for now, since we are not using virtual memory yet

Andyhhp
Moderator
Posts:387
Joined:Tue Oct 23, 2007 10:05 am
Location:127.0.0.1
Contact:

Re: GDT Problem

Post by Andyhhp » Thu Sep 24, 2009 5:51 pm

lol - thats supposed to be the present bit in the Page Table Entries, not the GDT.

That would explain the problems
Image

oib111
Posts:38
Joined:Sat Aug 29, 2009 6:44 am

Re: GDT Problem

Post by oib111 » Thu Sep 24, 2009 8:43 pm

Lol...ok, can anyone look at that memory problem though?

User avatar
Mike
Site Admin
Posts:465
Joined:Sat Oct 20, 2007 7:58 pm
Contact:

Re: GDT Problem

Post by Mike » Thu Sep 24, 2009 10:47 pm

Hello,

That bit in the GDT tells the processor if the segment is in memory or not. If it is 0, the segment is not in memory and thus cannot be used. If it is 1 (should be), the segment is in memory and can be used. It is an error in the tutorial - it should be 1 if it is in memory in all cases and will be corrected. :)
Lead Programmer for BrokenThorn Entertainment, Co.
Website: http://www.brokenthorn.com
Email: webmaster@brokenthorn.com

oib111
Posts:38
Joined:Sat Aug 29, 2009 6:44 am

Re: GDT Problem

Post by oib111 » Fri Sep 25, 2009 12:01 am

Thanks! I have a question about the memory detection though. What is it really detecting? I thought it was detecting the total amount of RAM installed in the system, and then certain areas were available and some were reserved (as designated by the memory map). But it seems that it's getting some random value and the memory map contains the real info (all types that can be used combined equals the total memory)? Or does Bochs treat the amount of RAM you specify as the amount of usable memory and not total memory?

EDIT:

Just realized I had some memory holes. It seems Bochs gives me 4GB of RAM but the parts I can actually use are 128MB. So I have around 3968MB worth of memory holes (there are two). Now here's a question, is it safe to set those memory holes as in use as well or are they bad memory? Because it's going to be very annoying if I have to keep track of where and how big the holes are and then rewrite my functions to compensate for them. Also, will this happen on a real computer, or is it just because I'm using an emulator (I read up on wiki.osdev.org that memory size and maps seem to be problematic on emulators/VMs)?

Andyhhp
Moderator
Posts:387
Joined:Tue Oct 23, 2007 10:05 am
Location:127.0.0.1
Contact:

Re: GDT Problem

Post by Andyhhp » Fri Sep 25, 2009 9:19 pm

Memory holes are literally holes in memory - it is unsafe to use them normally

In some cases, they are there for backward compatability; in other cases, they are memory mapped hardware that must be used carefully.

AFAIR, all modern computers have a whole between 15-16MB of physical memory and one for the graphics card (on a 32bit computer without PAE, this is why 4GB of ram only shows up as 3.5GB usable etc.)
Image

oib111
Posts:38
Joined:Sat Aug 29, 2009 6:44 am

Re: GDT Problem

Post by oib111 » Fri Sep 25, 2009 10:59 pm

I don't see a memory hole between 15-16MB?
0x0-0x9f000 (total size 0x9f000)
0x9f000-0xa0000 (total size 0x1000)
non contiguous by 0x48000 bytes
0xe8000-0x100000 (total size 0x18000)
0x100000-0x7ff0000 (total size 0x7ef0000)
non contiguous by 0xf7fd0000 bytes
0xfffc0000-0x100000000 (total size 0x40000)
Couple questions.

1. If I'm reporting memory to the user, would it be better to report the amount of memory I can use initially or all memory (including the reserved areas).
2. Does the memory map go from lowest to highest address, and if it does, is the last region described in the memory map always end at the last physical address of memory?
3. Is there any way to get GRUB to pass me the size of my kernel in bytes or sectors?

Post Reply