where is gdt located?

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.
User avatar
yemista
Member
Member
Posts: 299
Joined: Fri Dec 26, 2008 12:31 pm
Location: Boston
Contact:

where is gdt located?

Post by yemista »

Ok, I am just curious, gdt offset is only 4 bytes, so does the cpu automatically use ds to reference it? How codes it know what segment to use to find the gdt? Also, lets say I want a pointer to the gdt from my c source. Would I use just a regular int(4 byte) pointer? What about the segment?
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Re: where is gdt located?

Post by jal »

yemista wrote:Ok, I am just curious, gdt offset is only 4 bytes, so does the cpu automatically use ds to reference it? How codes it know what segment to use to find the gdt? Also, lets say I want a pointer to the gdt from my c source. Would I use just a regular int(4 byte) pointer? What about the segment?
The GDT address is a linear address. And preferably, you do not use segments. For example, gcc does not (and cannot) use segments, so it assumes all pointers are linear. What (cross-)compiler do you use?


JAL
User avatar
yemista
Member
Member
Posts: 299
Joined: Fri Dec 26, 2008 12:31 pm
Location: Boston
Contact:

Re: where is gdt located?

Post by yemista »

I am developing under linux using gnu tools. I know its a linear address, but the gdt offset entry is only 4 bytes, so there is a limit as to where the gdt can be located. Does this mean that the gdt can only exist within all the addresses that can be expressed through 4 bytes?
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Re: where is gdt located?

Post by AJ »

Hi,
yemista wrote:Ok, I am just curious, gdt offset is only 4 bytes, so does the cpu automatically use ds to reference it? How codes it know what segment to use to find the gdt?
The lgdt instruction uses DS by default.
Also, lets say I want a pointer to the gdt from my c source. Would I use just a regular int(4 byte) pointer?
Firstly, we need to address a couple of assumptions here. An int is not necessarily 4 bytes and the size of a pointer is not necessarily the same as the size of an integer. Do not assume either of these, particularly if you want any level of platform independence.

Secondly, you can certainly get a regular pointer to your GDT:

Code: Select all

struct gdt
{
  // gdt stuff in here
}

struct gdt* pGdt = [known address of gdt];

void myFunction()
{
   pGdt->access = [GDT access value];
}
... and so on.
What about the segment?
This depends. You can create the GDT wherever you like. If you are using a flat memory model, DS will automatically be used by your C compiler and all is well. If you have a segmented memory model and are using a C compiler, good luck :wink:

Cheers,
Adam
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Re: where is gdt located?

Post by AJ »

Addition, given new replies since I started typing!
Does this mean that the gdt can only exist within all the addresses that can be expressed through 4 bytes?
If you are on a 32 bit system, you only need 4 bytes to represent every valid virtual address. On x86-64, GDTR extends to 64 bits, so you can put the GDT anywhere.

Cheers,
Adam
User avatar
yemista
Member
Member
Posts: 299
Joined: Fri Dec 26, 2008 12:31 pm
Location: Boston
Contact:

Re: where is gdt located?

Post by yemista »

Ok, but lgdt and sgdt implicitcly assume the ds segment? 4 bytes cannot get you all the addresses. But that does this mean gdt references itself to find itself? For example, if you are in protected mode, ds will be a selector into gdt, so ds:gdt should give you the address of the gdt. The one thing that confuses me though is, when making the switch in my bootloader, I originally used 0x0000 for the data segment. gdt therefor was stored at 0x0000:gdt using real mode addressing. So I use lgdt to load this address into the gdt. The next thing I did was change ds to the second entry in the gdt, and made its base 0x0100, so ds:gdt no longer references what it did before, so if the cpu uses ds implicitly to find the physical address of the gdt, it should no longer do so. How does this work? I havnt tried anymore sgdt or lgdt insructions after that point, but any memory reference should go through the gdt at this point and it does work, but to go through the gdt it must know where it is. Obviously it works, but I just dont see how.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: where is gdt located?

Post by Combuster »

"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Re: where is gdt located?

Post by AJ »

The base and offset of DS will only change when you explicitly reload DS.

Cheers,
Adam

[Edit: Combuster got there first!]
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Re: where is gdt located?

Post by jal »

yemista wrote:4 bytes cannot get you all the addresses
As AJ pointer out, in 32 bit it can. You have not said you want to operate in 64-bit mode, in which case it is 8 bytes, not 4, and you have to tell your compiler to use long mode as well (afaik).


JAL
User avatar
yemista
Member
Member
Posts: 299
Joined: Fri Dec 26, 2008 12:31 pm
Location: Boston
Contact:

Re: where is gdt located?

Post by yemista »

yes i understand that, i am using 32 bits, but what i meant was the offset of the gdt is only 4 bytes long, but 4 bytes does not address all the RAM, so the cpu needs some mechanism to locate the gdt in addition to that 4 byte offset. But I think my questions been answered anyways by combuster. I am not even interested in the physical mechanism going on or how the descriptor cache works, i just was not aware it existed and was wondering how this problem was solved. thank you
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Re: where is gdt located?

Post by AJ »

yemista wrote:yes i understand that, i am using 32 bits, but what i meant was the offset of the gdt is only 4 bytes long, but 4 bytes does not address all the RAM
Yes it does.

Exceptions:
- Physical RAM if you are using PAE (doesn't matter because you still only have a 32 bit linear address space).
- Long Mode (doesn't matter because the GDT offset is extended to 8 bytes (64 bits).

Cheers,
Adam
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: where is gdt located?

Post by Brendan »

Hi,
AJ wrote:Exceptions:
- Physical RAM if you are using PAE (doesn't matter because you still only have a 32 bit linear address space).
- Long Mode (doesn't matter because the GDT offset is extended to 8 bytes (64 bits).
Correct :)

[off-topic]
For PAE, the problem is the "Page Directory Pointer Table", which must be below 0xFFFFFFFF because CR3 is still only 32-bit (even though page directories, page tables and pages all use "36-bit or larger" physical addresses). ;)
[/off-topic]


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Re: where is gdt located?

Post by jal »

yemista wrote:yes i understand that, i am using 32 bits, but what i meant was the offset of the gdt is only 4 bytes long, but 4 bytes does not address all the RAM
Please explain why you think this. Remember, 4 bytes == 32 bits.


JAL
User avatar
yemista
Member
Member
Posts: 299
Joined: Fri Dec 26, 2008 12:31 pm
Location: Boston
Contact:

Re: where is gdt located?

Post by yemista »

I guess I should have sat down and done the math. 32 bits can fully address 4 gigs, I dont know why that slipped my mind at the time. I guess the confusion comes from, if that is the case, what is the point of even having selectors? But I guess the answer is for security reasons, not addressing ones. My confusion came from writing my bootsector, I tried a far jump to 0x0000:0010001, using pmode, but it wrapped around and I did not understand until I realized a segment limit is ffff so that caused it wrap around, and I was wondering why pmode could not address every address. Now I see this is not due to a limitation in addressing, but it happens to be how pmode works, and I guess the ffff limit has also to do with security issues because no one process should need that much addressing
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Re: where is gdt located?

Post by AJ »

yemista wrote:My confusion came from writing my bootsector, I tried a far jump to 0x0000:0010001, using pmode, but it wrapped around and I did not understand until I realized a segment limit is ffff so that caused it wrap around, and I was wondering why pmode could not address every address. Now I see this is not due to a limitation in addressing, but it happens to be how pmode works, and I guess the ffff limit has also to do with security issues because no one process should need that much addressing
In true 32 bit PMode, a jump to 0x0000:0x0010001 shouldn't wrap - it should give you a General Protection Fault for attempting to jump somewhere in the null segment. If you jump to 0x08:0x0010001, assuming that your 32 bit code segment is your first segment, you should be ok.

I think your confusion could be down to one of the following:
1) Are you using 16 bit PMode. In that case, things could well be wrapping. Check the bits in your GDT segments carefully.
2) Have you not enabled gate A20 (and have a BIOS that does not do this for you)? If so, it is likely that you will only be able to access every other megabyte of RAM (0-1MiB, 2-3MiB...).

TBH, my suggestion to you would be to provide memory protection via paging instead of segmentation. Segmentation is fast becoming "legacy" - particularly with how 64 bit processors treat segmentation (they ignore it!). Simply set up a flat, 4 gig code and data segment and then forget about segments.

Cheers,
Adam
Post Reply