Page 1 of 1
GDT Entry Offset and Paging
Posted: Wed Jan 17, 2007 4:02 pm
by Tolga
Hi. I dont understand that; when paging active, in GDT Entry, offset value indicates what? Is already contain memory offset? If true, i can adjust it half of a page. And this is wrong. Because, example, i can adjust it with 0x1800. And this offset start at half of second page.
Thanks.
Re: GDT Entry Offset and Paging
Posted: Thu Jan 18, 2007 1:48 am
by Brendan
Hi,
Tolga wrote:Hi. I dont understand that; when paging active, in GDT Entry, offset value indicates what? Is already contain memory offset? If true, i can adjust it half of a page. And this is wrong. Because, example, i can adjust it with 0x1800. And this offset start at half of second page.
Segments can begin and end at any linear address, and you can (for e.g.) have a segment that begins at 0x00001800 (half way through the second page).
Why do you think there's anything wrong with that?
The OS can make all segments start at 0x00000000 and end at 0xFFFFFFFF, or make sure all segments start and end on page boundaries, or adjust segments to suit the exact purpose (for e.g. adjust the limit on CS to be the last byte of code).
Cheers,
Brendan
Posted: Thu Jan 18, 2007 3:43 am
by Combuster
Maybe this helps
Code: Select all
(segmentation) (paging)
virtual address --------------> ... -------------> physical address
Posted: Thu Jan 18, 2007 4:14 am
by INF1n1t
They say in the intel manual, you can overlap pages and segmentation. You can put several pages into a segment and several segments into a page. But is it effective to do so? I think, not...
However, you map virtual addresses to physical ones and like Combuster said: you take the offset go through the segment translation mechanism and then go through the paging mechanism to translate the absolute offset into a page offset.
Posted: Thu Jan 18, 2007 9:34 am
by Tolga
Hmm. Actually the real question is that:
When paging active, how do processor use offset value in gdt entry?
# Does it use like this? (example 0x1800)
Code: Select all
0000000000 0000000001 100000000000
---------- ---------- ------------
Page Page Index Page Offset
Directory
# Or does it use this offset like segmentation offset?
Which is true?
Thanks.
Posted: Thu Jan 18, 2007 11:02 am
by Brendan
Hi,
For something like "mov eax,[ds:0x1234]" the CPU compares the value 0x1234 to the segment limit (in a hidden register in the CPU), and then adds the base address for the segment (also from a hidden register in the CPU). The hidden segment limit and segment base are set (loaded into the CPU) from the GDT or LDT entry when a segment register is loaded.
If the base address for the segment is 0x87650000 then the CPU would come up with the address 0x87651234.
Then, if paging is enabled the CPU would search for the physical page that corresponds to the linear address 0x87651000 and load EAX from offset 0x00000234 in that physical page.
The exact details of how the CPU finds the physical page that corresponds to a linear address depends on what's in the TLB's and which type of paging is enabled. For "plain 32-bit" paging, it'd look for an entry in the TLB for 0x87651000 and use that if it's present. If not, it'll use CR3 to find the physical address of the page directory, then it'll use the highest 10 bits of the linear address to determine which entry in the page directory contains the physical address of the page table. Then the CPU uses bits 12 to 21 in the linear address to determine which entry in the page table contains the physical address of the page it needs.
In this case, it'd use entry number 0x43B in the page directory to find the physical address of the page table, entry number 0x251 in the page table to find the physical page, and offset 0x234 in that physical page.
To complicate things, it's possible for an access to be split across pages. For e.g. if the DS segment base is 0x00000FFE and you do "mov eax,[ds:0x00001000]" then the CPU will try to get 4 bytes of data from 0x0001FFE to 0x0002001. In this case the CPU needs to find 2 seperate physical pages (one for the first 2 bytes and the other for the last 2 bytes).
For loading data from a GDT descriptor it's the same thing, except that the GDT base address and GDT limit is used instead of the hidden segment register base and limit. For example, for "mov ax,0x0008; mov ds,ax" the CPU adds the GDT base to 0x0008, and then uses the page tables, etc to find the physical address that corresponds to it. This means you'd want to align your GDT on an 8 byte boundary so that the CPU never needs to find 2 seperate physical pages when a segment register is loaded.
Cheers,
Brendan
Posted: Thu Jan 18, 2007 5:44 pm
by Tyler
Combuster wrote:Maybe this helps
Code: Select all
(segmentation) (paging)
virtual address --------------> ... -------------> physical address
I believe "linear address" is in the middle... in intel terms