A question or six about the GDT.

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.
Locked
jaswax
Posts: 23
Joined: Sat Jan 19, 2008 11:26 am
Location: Texas

A question or six about the GDT.

Post by jaswax »

First I just wanted to say this site kicks it. Thanks for the info.

I have done many searches and read lots of post about OS Dev, GDT, Protected Mode, etc but I have some questions still un-answered.

I am developing under Linux. Using GCC, NASM and LD. QEMU is this emulator that I am using.

Q1: From what I have seen in the examples, posts and tutorials the GDT entries for code and data just use a base of 0 and a limit of 0xffff with granularity set so that you have 4GB of addressable space. I have seen very few examples with any thing else. So the questions is: Why? Is it better to set up the GDT this way for some reason? If so, what is that reason?

Q2: I have not seen any examples with code and data mapped to different locations. They are always the same. So can the code and data descriptors address different locations instead of the same memory address?

Q3: Is there something wrong with this GDT? According to the documentation and tutorials this should be possible but it hoses up my emulator. I don't get a dump. (Depending on the answers to the questions above, answering this may not be necessary!)

Code: Select all

gdt:

null:
        dd 0
        dd 0

kernel_code:
        dw 0x0022
        dw 0
        db 0
        db 10011010b
        db 11001111b
        db 0

kernel_data:
        dw 0x0022
        dw 0xfff1
        db 0x22
        db 10010010b
        db 11001111b
        db 0

isr_code:
	dw 0x0022
        dw 0xffe2
        db 0x45
        db 10011010b
        db 11001111b
        db 0

gdt_end:

gdt_desc:
        dw gdt_end - gdt - 1
        dd gdt 
Thanks in advance for any help.
xyzzy
Member
Member
Posts: 391
Joined: Wed Jul 25, 2007 8:45 am
Libera.chat IRC: aejsmith
Location: London, UK
Contact:

Re: A question or six about the GDT.

Post by xyzzy »

jaswax wrote:First I just wanted to say this site kicks it. Thanks for the info.

I have done many searches and read lots of post about OS Dev, GDT, Protected Mode, etc but I have some questions still un-answered.

I am developing under Linux. Using GCC, NASM and LD. QEMU is this emulator that I am using.

Q1: From what I have seen in the examples, posts and tutorials the GDT entries for code and data just use a base of 0 and a limit of 0xffff with granularity set so that you have 4GB of addressable space. I have seen very few examples with any thing else. So the questions is: Why? Is it better to set up the GDT this way for some reason? If so, what is that reason?

Q2: I have not seen any examples with code and data mapped to different locations. They are always the same. So can the code and data descriptors address different locations instead of the same memory address?
It's only really useful to set it up any other way if you're planning to use the segmentation provided on x86 processors for memory protection. If you're going to use paging, just setting each segment to cover the entire address space is far easier.
User avatar
XCHG
Member
Member
Posts: 416
Joined: Sat Nov 25, 2006 3:55 am
Location: Wisconsin
Contact:

Re: A question or six about the GDT.

Post by XCHG »

jaswax wrote:Q1: From what I have seen in the examples, posts and tutorials the GDT entries for code and data just use a base of 0 and a limit of 0xffff with granularity set so that you have 4GB of addressable space. I have seen very few examples with any thing else. So the questions is: Why? Is it better to set up the GDT this way for some reason? If so, what is that reason?
Segmentation is something that so many people are still hating and probably will until it is there. But it could be really useful when used with paging. The reason we set the GDT up like that is to have a flat 4GB address space in IA-32. Also instructions such as SYSENTER/SYSEXIT require you to have a code segment which has a 4GB limit with the granularity bit set and noncomforming and etc. So you are pretty much forced to have that sort of GDT when working with fast system calls and etc.

jaswax wrote:Q2: I have not seen any examples with code and data mapped to different locations. They are always the same. So can the code and data descriptors address different locations instead of the same memory address?
Yes. You must use paging with segmentation to be able to take advantage of all the addressing modes available in IA-32.
On the field with sword and shield amidst the din of dying of men's wails. War is waged and the battle will rage until only the righteous prevails.
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:

Post by Combuster »

May I add that most GDTs have the limit set to 0xFffff (yes, 5), page granular. That 5th F is contained in one of the other fields so that in all cases here you'll have a segment with a pretty large limit.

If you want more verbose error messages, try the same thing in Bochs. In any case, make sure that your segment base and offset matches the real location of your code.
"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 ]
jaswax
Posts: 23
Joined: Sat Jan 19, 2008 11:26 am
Location: Texas

Thank you

Post by jaswax »

Thanks for all the replys.

I think what I am going to do next is read about paging. I do want to use this eventually but I have not read much on it.

After reading the answers I did find some bugs in my code. So I am going to go fix that and try again.

If any one wants to add anything, please feel free.
User avatar
bewing
Member
Member
Posts: 1401
Joined: Wed Feb 07, 2007 1:45 pm
Location: Eugene, OR, US

Post by bewing »

I was originally thinking of keeping data and code regions separate. But I changed my mind, and now I just use the standard 0-base, 4G limit stuff.

The reason is that (while this first version of the os is 32bit) I am eventually planning on moving the completed kernel to a 64bit environment, and in a 64bit environment, segments don't really work anymore (without a lot of trickery). And if segments don't work, then playing cute tricks with the GDT is pretty much worthless.

Also, if you are playing with the segment registers, then you have to save them carefully on every task switch -- and I decided I didn't want to bother with that.
Locked