When the logical address is converted to a linear address, as we said, using the first 13 bits of the value in the segment register as an index to index the global descriptor chart,
in Linux, it is funny that it intentionally uses the numerical to circumvent the segmentation mechanism, and the memory management mainly uses the paging mechanism.
how it is.
let's see what Linux puts in GTD. View File Arch/i386/head. S
. Quad 0X00CF9A000000FFFF/* 0x60 kernel 4GB Code at 0x00000000 * *
. QUAD0X00CF92000000FFF/* 0x68 kernel 4GB data at 0x00000000 * *
. QUAD0X00CFFA000000FFFF/* 0x73 user 4GB Code at 0x00000000 * *
. quad0x00cff2000000ffff/* 0x7b User 4GB data at 0x00000000 * *
Only 12-15 items were picked up here, and look below.
Let's take a look at the number of selectors in each segment register, and see the definition in include/asm-i386/segment.h.
Include/asm-i386/segment.h
#defineGDT_ENTRY_DEFAULT_USER_CS 14
#define__USER_CS (Gdt_entry_default_user_cs * 8 + 3)
#defineGDT_ENTRY_DEFAULT_USER_DS 15
#define__USER_DS (Gdt_entry_default_user_ds * 8 + 3)
#defineGDT_ENTRY_KERNEL_BASE 12
#defineGDT_ENTRY_KERNEL_CS (gdt_entry_kernel_base + 0)
#define__KERNEL_CS (Gdt_entry_kernel_cs * 8)
#defineGDT_ENTRY_KERNEL_DS (gdt_entry_kernel_base + 1)
#define__KERNEL_DS (Gdt_entry_kernel_ds * 8)
Replace the macro with a value:
#define__USER_CS 115 [000000001110 0 11]
#define__USER_DS 123 [000000001111 0 11]
#define__KERNEL_CS 96 [00000000 1100 0 00]
#define__KERNEL_DS 104 [00000000 1101 0 00]
The square brackets are followed by the 16-bit two representation of these four segment selectors, and their index numbers and T1 field values can also be calculated.
__user_cs index= t1=0
__user_ds index= t1=0
__kernel_cs index= t1=0
__kernel_ds index= t1=0
As you can see, the user code snippet registers Usre_cs 115
Take it apart and use it to index GDT when you find the 14th item, you can see
. Quad 0X00CFFA000000FFFF/* 0x73 user 4GB Code at 0x00000000 * *
第16-31位 is all 0, that is, the starting address of the paragraph is 0, then the logical address is converted to a linear address
That is, the 0x00000000+ offset = offset.
This is not a coincidence, but all the situation is the case, do not believe that you can use the GDB debugger output register in the value of the check, is not 115 or 123. (Segment Register)
Here you can look at the functions you write casually and then debug the results.
You can see the value of several registers such as CS has always been the user Cs and DS that is 115 123.
Not by chance ....
Then you can see that the logical address and the linear address have the same form (that is, the numbers are the same.) )
So Linux memory management is mainly based on paging, avoid segmentation (but hardware requirements are segmented, so the avoidance of the means), but the following 3-bit (segment selector 3 bits to represent the level of the segment, 00-11 is useful, access to GDT or LDT is useful).
This diagram may be clearer:
Then by line-object
We know that Linux in the user process linear address can be addressed to the range is 0-3g, then it is necessary to advance the 3g virtual memory of the page table are built. In general, the physical memory is far less than 3G, plus a lot of processes are running, it is impossible to advance each process to establish a 3G Linear Address page table. Linux uses a CPU mechanism to solve this problem. After the process is created we can fill in the table entry values for the page catalog table 0,cpu when looking up the page table, if the contents of the table entry is 0, a page fault exception is raised, and the process pauses, and the Linux kernel can then assign a physical sheet through a series of complex algorithms and fill in the address of the physical page. The process resumes execution again. Of course the process is blinded in the process, and its own sense of access to the physical memory is normal.