Saturday, July 13, 2013

Protected Mode Segmentation

In Real Mode, the segment registers contain a segment selector which is the base address of the segment.

In protected mode, the segment selector points to a specific entry in a table.

There are 2 types of descriptor table - GDT and LDT. There is only one GDT shared by all tasks in the entire system. The LDT can be used by one or one group of tasks. GDT is located by using a special register GDTR. It is manipulated by privileged instruction executable by OS.

Each segment register pairs with an invisible part called the segment cache register, which contains the content of the corresponding 8-bytes table entry (called descriptor) in GDT or LDT.

The selector is 16-bits in length. The highest 13 bits specifies an entry in the descriptor table. In other words, there is 8K entries in the descriptor table. GDT (Global Descriptor Table). The next bit indicate if the table is GDT or LDT. The last 2 bits indicate the privilege level of the selector.

The descriptor is 64-bits in length and contains
1. base address of the segment (32-bits)
2. size of the segment (20-bits). The G-flag (1-bit) is used to interpret the size (clear means the size is number of byte from 1 byte to 1M, set means the size is 4K increment from 4K to 4M)
3. S-flag indicate if it is a system segment (clear) or an application segment (set). System segment descriptors are used to jump to segments that have higher privilege that the current executing task
4. Type (4-bits) used with S-flag to further define the segment. If the descriptor is an application section, bit 11 defines if it is code (set) or data (clear). For data segment, bit 10/9/8 represent the direction of growth (clear = up and set = down), RO/RW and if it is recently accessed respectively. For code segment, the last 3 bits represent if the code is conforming or not (set), Execute-only or Execute/READ and if it is recently accessed. A non-conforming code segment cannot be accessed by a program that is executing with less privilege (higher DP value). In other words, RPL <= CPL <= DPL
5. DPL (descriptor privilege level) 
6. P-flag defines if the segment is currently in memory (set)
7. AVL defines if the segment is available for OS use 
8. L-flag defines if the segment contains 64-bit code. Most IA-32 processors clear this bit.
9. D/B flag means differently when the segement is code, data or stack.

 The first descriptor entry is always empty called null segement descriptor and the selector pointing to this entry is call null selector.

There are other types of descriptor in GDT:
1. Task State Segment (TSS)
2. Local Descriptor Table (LDT) 
3. Code, data or stack memory segment to be accessible by multiple task
4. Procedure call gate used to control access to privilege program (e.g. IO routine) by less privileged ones (user)
5. Task gates used to switch to other task. LDT (Local Descriptor Table) is accessed via GDT (see 2).

The 16-bit segment selector is stored in TSS so that it could be loaded at task switching. TSS is a memory area that keeps the context of a task when it is switced out.  It contains the general register, the segment register, the LDT selector field, EFlag, EIP, ESP, CR3 (Page Directory Address) etc. When a user program (privilege level 3) called into a more privileged program (level 0 to 2), the processor also automatically create a new stack. Therefore, TSS also keeps 3 additional ESP to record the stack top for each level.

No comments: