Descriptor Table

Descriptor table is a 64 bytes length data set that
determains beginning of memory address, size of it, limitation of it,
access mode and several attribute bits.

Here is a depict of Descriptor.

31 24 16 8 0 +-----------------------------+-------------------------------+ | | | 3 | Base Address 0 - 15 | Segment Limitation 0 - 15 | 0 | | | +-----------------------------+-------------------------------+ | |2 | Limit | | | 7 | Base 24-31 |3 | 16-19 | | Base 16-23 | 4 | |G | | | | +-----------------------------+-------------------------------+

Base address is 32-bit, so address space is 4Gbytes.
Segmentation Limit is 20-bit, and when granuality bit (G in depict)
is set, page size is 4kbytes.
So maxmum size of segment is 1Mbytes x 4kbytes = 4Gbytes.

At boot up time, temporary gdt is set. The contents is in next code.
(${linux src}/arch/i386/boot/setup.S)

gdt:
        .fill GDT_ENTRY_BOOT_CS,8,0

.word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb) .word 0 # base address = 0 .word 0x9A00 # code read/exec .word 0x00CF # granularity = 4096, 386 # (+5th nibble of limit)

.word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb) .word 0 # base address = 0 .word 0x9200 # data read/write .word 0x00CF # granularity = 4096, 386 # (+5th nibble of limit) gdt_end:

The 7bit of the last word ("G" in depict above) is graunaliry.
If this bit is set, page size is 4k (4096).
0x00CF & 0x0080 is true, page size is 4k.

There are two entries of global descriptor, for code and for data.

The first word 0xFFFF is a lower part of limitation and 0-3bit of
lowest byte of the lastword(0x00CF) is upper part of limitation.

So, limitation is 0xFFFFF, it is 1M. but limitaion is limit for page
and page size is 4k. In result, limitatin is 4Gbytes.

Second word is lower part of base adress (0x0000),
0-7bit of thrid word (0x00 of 0x9A00) and 8-15bit of forth word (0x00 of 0x00CF)
is upper part of base address.
So, base address is 0x00000000.

The difference of these two descriptors is whether R/W bit of thrid
word is set or not.

Segment for code and data start at 0x0000000 and page size is 4K-byte,
limitation is 0xFFFFF, which means 1K pages, that is 4Gbyts.
The hole address space of 32-bit processor can be accessed.

GDT and LDT

There are two type of descriptor table, "Global Descriptor Table"(GDT)
and "Local Descriptor Table"(LDT).

Global discriptor table is literally global for every process.
This table handles the share code of program and in linux
kernel is a this type of code.

Local Descriptor Table is peculiar to each process.

For each descriptor table, there is a regtistor in processor to store
it to determain which segment is to be used.

"Global Descriptor Table Register"(GDTR) and
"Local Descriptor Table Register"(LDTR).

One GDTR for Global Descriptor Table obviously,
but one LDTR for every Local Descriptor Table.

When upper most bit of cr0 (Control Register) is set,
Paging Unit is working to translate from virtural address to physical address.

cr3 register points the "Page Directory Entry" to do translate
and its value is loaded from descriptor table.

Task Switch

In real mode, memory address is represented like cs:offset.
The address is culculated by cs << 4 + offset.

But in protect mode, processor works in different concept.
Each application has its own segment on memory,
and in order to determain which segment to be used,
intel processor uses "Selector".

"Selector Register" that stores selector's value are
cs, ds, es, ss, fs, gs.

selector is 16-bit length data and upper 13-bit is used as index to
point a Local Descriptor Table.

When selector is changed, local descroptor table register is
loaded to change the segment to selected one.

Descriptor Table is 64-bit data chunk, but registor that stores
these data is 48-bit.
This register has beginning and size and limitation of the segiment.

To determain the segment that an application uses,
processor uses 16-bit selector register and 48-bit descriptor register.

Instead of accessing to the physical memory, storing descriptor value
into register makes processor fast to determain which segment
should be used.

When a task is switched, processosr exchange of content of LDTR
which points to descriptor table for a task that is to be running.

Task Status Segment

"Task Status Segument"(TSS) is also used to exchange tasks.
This structure store the status of register and selector and other
many data for each task.

When switch a task to other, processor loads the selector
for a new task by using "jmp" instruction or through "call gate".

"jmp" loads the selector into "TSS Registor"(TR) and farmware on
a processor does job to load the Local Descriptor Table pointer
into LDTR and TSS data is reloaded into registers for a new task.

Then a new task begin to restart it execution from where it is stolen.

inserted by FC2 system