How to make a GDT?
- Schol-R-LEA
- Member
- Posts: 1925
- Joined: Fri Oct 27, 2006 9:42 am
- Location: Athens, GA, USA
Re: How to make a GDT?
Ah, OK, thank you for that correction.
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
Re: How to make a GDT?
So if I'm correct, I'll have 4 of these structs set up.Schol-R-LEA wrote: Now, if you want to use a C struct to organize that memory, you will want something like this:
Code: Select all
struct __attribute__((packed, aligned(4))) GDT { uint16_t base_low; uint16_t limit_low; uint8_t base_mid; uint8_t access; uint8_t limit_high_and_flags; uint8_t base_high; };
So how do I load this into the GDT?
-
- Member
- Posts: 5562
- Joined: Mon Mar 25, 2013 7:01 pm
Re: How to make a GDT?
Specifically an array of four of these structs.zap8600 wrote:So if I'm correct, I'll have 4 of these structs set up.
The array of structs is your GDT. Are you asking how to put information into your GDT, or are you asking how to tell the CPU to use your GDT?zap8600 wrote:So how do I load this into the GDT?
Re: How to make a GDT?
Sorry. I was confused.Octocontrabass wrote: The array of structs is your GDT. Are you asking how to put information into your GDT, or are you asking how to tell the CPU to use your GDT?
I meant telling the CPU where the table is. Like this. My inline assembly is bad, and I'm very dumb, so I'm not exactly sure how to do it.
Also, how would I find the values for base_low, mid and high? Same question for limit_low and limit_high_and_flags.
Also, how would I add both limit_high and the flags to limit_high_and_flags?
Sorry if this is too many questions. I'm just dumb and confused.
Re: How to make a GDT?
You don’t “find” those values, you choose them according to your requirements. Where do you want your segments to start; how big do you want them to be; those are design decisions that you make.
-
- Member
- Posts: 5562
- Joined: Mon Mar 25, 2013 7:01 pm
Re: How to make a GDT?
Create a GDTR descriptor (you can also use a struct) and then use the LGDT instruction to load the GDTR descriptor into GDTR. After you tell the CPU where your GDT is, you should load new selectors into the segment registers. Your code might look something like this, if you use a struct for the GDTR descriptor:zap8600 wrote:I meant telling the CPU where the table is.
Code: Select all
struct __attribute__((packed)) GDTR
{
uint16_t limit;
uint32_t base;
};
void example( uint32_t base, uint16_t limit )
{
struct GDTR gdtr = { limit, base };
asm( "lgdt %0" :: "m"(gdtr) );
asm( "ljmp %0,$1f\n1:" :: "i"(KERNEL_CODE_SEG) );
asm( "mov %0, %%ds" :: "r"(KERNEL_DATA_SEG) );
asm( "mov %0, %%es" :: "r"(KERNEL_DATA_SEG) );
asm( "mov %0, %%ss" :: "r"(KERNEL_DATA_SEG) );
//asm( "mov %0, %%fs" :: "r"(KERNEL_FS_SEG) );
//asm( "mov %0, %%gs" :: "r"(KERNEL_GS_SEG) );
}
Take your base address and put the low 16 bits into base_low, the next 8 bits into base_mid, and the top 8 bits into base_high.zap8600 wrote:Also, how would I find the values for base_low, mid and high?
Take your limit and put the low 16 bits into limit_low and the high four bits into limit_high_and_flags. The limit is only 20 bits; it indicates either bytes or pages according to the granularity flag.zap8600 wrote:Same question for limit_low and limit_high_and_flags.
The high four bits of the limit go into the low four bits of limit_high_and_flags. Four bits of flags go into the high four bits of limit_high_and_flags. You can use bitwise operations to place the values you want in the correct locations. The Intel and AMD manuals have excellent diagrams showing where everything goes.zap8600 wrote:Also, how would I add both limit_high and the flags to limit_high_and_flags?
Re: How to make a GDT?
I see what I'm doing wrong. I'm confusing the GDT struct for the Segment Struct. I'm very dumb.Octocontrabass wrote:Create a GDTR descriptor (you can also use a struct) and then use the LGDT instruction to load the GDTR descriptor into GDTR. After you tell the CPU where your GDT is, you should load new selectors into the segment registers. Your code might look something like this, if you use a struct for the GDTR descriptor:
Unlike the earlier example, this struct must be packed because the compiler would insert padding otherwise. Alignment is unnecessary.Code: Select all
struct __attribute__((packed)) GDTR { uint16_t limit; uint32_t base; }; void example( uint32_t base, uint16_t limit ) { struct GDTR gdtr = { limit, base }; asm( "lgdt %0" :: "m"(gdtr) ); asm( "ljmp %0,$1f\n1:" :: "i"(KERNEL_CODE_SEG) ); asm( "mov %0, %%ds" :: "r"(KERNEL_DATA_SEG) ); asm( "mov %0, %%es" :: "r"(KERNEL_DATA_SEG) ); asm( "mov %0, %%ss" :: "r"(KERNEL_DATA_SEG) ); //asm( "mov %0, %%fs" :: "r"(KERNEL_FS_SEG) ); //asm( "mov %0, %%gs" :: "r"(KERNEL_GS_SEG) ); }
So what should the size of it be? Do I find the size in the Intel and AMD Manual? I'm not really sure how large it should be. I'm using the segments from here.iansjack wrote:You don’t “find” those values, you choose them according to your requirements. Where do you want your segments to start; how big do you want them to be; those are design decisions that you make.
-
- Member
- Posts: 5562
- Joined: Mon Mar 25, 2013 7:01 pm
Re: How to make a GDT?
You don't "find" the size, you choose it. How do you want to use segments in your OS? Do you want to use segments at all? The values that go into your GDT depend on what you want the segments to do in your OS.zap8600 wrote:So what should the size of it be? Do I find the size in the Intel and AMD Manual? I'm not really sure how large it should be. I'm using the segments from here.
Re: How to make a GDT?
Well I would like to setup Userspace at some point. I also thought that the IDT required the GDT.Octocontrabass wrote: You don't "find" the size, you choose it. How do you want to use segments in your OS? Do you want to use segments at all? The values that go into your GDT depend on what you want the segments to do in your OS.
-
- Member
- Posts: 5562
- Joined: Mon Mar 25, 2013 7:01 pm
Re: How to make a GDT?
Both of those do require a GDT, but your GDT doesn't have to set up segmentation - you can use a "flat" setup that bypasses segmentation as much as possible.zap8600 wrote:Well I would like to setup Userspace at some point. I also thought that the IDT required the GDT.
So, do you want your OS to use segmentation? Or would you prefer the "flat" memory model that doesn't use segmentation?
Re: How to make a GDT?
If it isn't necessary, then I won't add it.Octocontrabass wrote: Both of those do require a GDT, but your GDT doesn't have to set up segmentation - you can use a "flat" setup that bypasses segmentation as much as possible.
So, do you want your OS to use segmentation? Or would you prefer the "flat" memory model that doesn't use segmentation?
So then what would the base and limit of the GDT be? Would it just be 0 for both?
Also, does paging require segmentation?
-
- Member
- Posts: 5562
- Joined: Mon Mar 25, 2013 7:01 pm
Re: How to make a GDT?
For a flat memory model, the base of the code and data segments should be 0 and the limit should be 0xFFFFFFFF bytes (0xFFFFF pages).zap8600 wrote:So then what would the base and limit of the GDT be? Would it just be 0 for both?
The base of the GDT itself is the address of the GDT. The limit is one less than the size of the GDT in bytes.
No. You can bypass segmentation and still use paging.zap8600 wrote:Also, does paging require segmentation?
Re: How to make a GDT?
I'm unsure how to write the setGDT function from here with inline assembly. How would I write it with the GDT descriptor struct
-
- Member
- Posts: 5562
- Joined: Mon Mar 25, 2013 7:01 pm
Re: How to make a GDT?
I already gave you example code for that.zap8600 wrote:I'm unsure how to write the setGDT function from here with inline assembly. How would I write it with the GDT descriptor struct
Re: How to make a GDT?
I'm sorry. I just wasn't sure it it would wotk with GRUB.Octocontrabass wrote: I already gave you example code for that.
Anyways, the OS booted with the GDT code. Now I have to figure out how to add newline support and a terminal scrolling implementation into the terminal driver. I'm an idiot, so it'll take a while for me to figure out. Then I need to add interrupts, the PIT, and the keyboard. I'll probably return here