I never take notes before. I forgot a lot of things and forgot to take notes. I started to record them today.
X86 segments
X86 Microprocessor has two working modes: real mode and protection mode. The actual mode is only for compatibility with previous products. Because linux is running
So here we only discuss the protection mode.
X86 segments differentiate memory addresses by segments. cs, ss, ds, es, fs, and gs are both segment registers.
The 16-bit high 13-bit is the index number of the segment description (the segment descriptor will be discussed immediately), and the TI-bit indication is the global description table (TI = 0) or partial description of the appendix (TI = 1), RPL is privileged 0 is the highest 3 lowest.
Segment descriptor:
We actually find a memory address through it. A descriptor occupies 8 bytes. Its structure will be discussed later.
Segment descriptor table:
You can think of it as a group of segment descriptors arranged on the continuous memory. Global Descriptor Table and Local Descriptor Table.
Scenario Analysis:
Assume that the following command mov cs 8 is
0000000000001000
If the index number is 1, go to the Global Descriptor Table and the privileged level is 0, where is the Global Descriptor Table. X86 adds two registers gdtr and ldtr to the protection mode. These two registers are used to store the base addresses of the Global Descriptor Table and the Local Descriptor Table respectively. For example, if the value in gdtr is 0x00020000, the segment descriptor address can be found based on Index 1. 0x00020000 + 8*1 = 0x00020008. Why is it 8, because a segment description occupies 8 bytes.
So how does the value in gdtr and ldtr come from? The operating of the protection mode must use these two values. Therefore, these two registers cannot be assigned again in the protection mode, but the descriptor table is created in the real mode, then, assign the base address of the table to the two registers. After the mode is switched to the protection mode, you can use these two values to find the two tables.
Now we have come to the segment descriptor. Let's take a look at the structure of the descriptor. The Structure of the segment descriptor is complicated. The most disgusting thing is how many different segment descriptors are there.
Base: Segment header address (the reason why it is divided into different regions is to be compatible with previous chips)
G: The segment size is measured in bytes or in multiples of 4096 bytes.
Limit: the offset of the last memory unit of the storage segment. If G = 0, the segment size is 0 ~ 1 MB, G = 1 segment size is 4 kb ~ 4 GB
S: If s = 0, this is a system segment. Otherwise, it is a common code segment or data segment.
TYPE features and access permissions of a TYPE segment
DPL descriptor privilege level 0 ~ 3
P: 0 indicates that the segment is no longer in primary storage. Linux always sets this value to 1 because it never exchanges the entire segment to the disk.
D or B. I have not understood this yet. Later, I only need to know that 32-bit access is 1.
AVL: linux ignores this
Now let's assume that we have found the segment descriptor at address 0x00020008 through the cs register
This value is set in the actual mode. It is compared with the following format chart.
We can see that the segment base address is 110000 00000010 00000000 00000000, that is, 0x30020000, G = 0, so the segment length is 2 ^ 20, that is, 1 MB, D = 1 is 32 address access DPL = 0 privileged level is the highest. S = 1 indicates the code segment or data segment. TYPE = 1010 indicates that the code segment is readable, executable, and not accessed. The base address segment 0x30020000 is found through privileged comparison.
A logical address is divided into two parts, the segment selection operator: offset. The segment selection operator is the value stored in cs in the example. We found a base address, and the offset is the linear address corresponding to the logical address. (At this time, we have not done paging, so linear addresses are physical addresses ). So far, we have achieved a logical address-to-linear address ing through segmentation.
We know that the program running on the operating system is actually a logical address operation after being translated into machine commands. However, if every command we execute is mapped in this way when we run the program, the efficiency is not too low. Therefore, x86 also provides six additional non-programming registers, which are exactly 8 bytes. When the segment register changes, it loads a register into the segment descriptor through the segment register index. Then, as long as the segment register remains unchanged, you do not need to index it through the selector. You can directly find the corresponding linear address through the 8-byte additional register.