Linux内存地址

来源:互联网 发布:什么时候出5g网络 编辑:程序博客网 时间:2024/06/03 23:06

Linux的分段

Linux uses segmentation in a very limited way. In fact, segmentation and paging are somewhat redundant, because both can be used to separate the physical address spaces of processes: segmentation can assign a different linear address space to each process, while paging can map the same linear address space into different physical address spaces.   The 2.6 version of Linux uses segmentation only when required by the 80 x 86 architecture.

GDT

Linux 2.6中每个CPU都含有一个GDT表,其中包含18项,比较重要的包含:

  • user code segment,user data segment,kernel code segment,kernel data segment
  • A Task State Segment (TSS, different for each processor in the system)
  • A segment including the default Local Descriptor Table (LDT), usually shared by all processes
  • Three Thread-Local Storage (TLS) segments    
GDT


All GDTs are stored in the cpu_gdt_table array, while the addresses and sizes of the GDTs (used when initializing the gdtr registers) are stored in the cpu_gdt_descr array.

LDT

Most Linux User Mode applications do not make use of a Local Descriptor Table. The default Local Descriptor Table is stored in the default_ldt array. It includes five entries, but only two of them are effectively used by the kernel.

Linux的分页

Starting with version 2.6.11, a four-level paging model has been adopted:
  • Page Table
  • Page Global Directory
  • Page Upper Directory
  • Page Middle Directory
For 32-bit architectures with no Physical Address Extension, The kernel keeps a position for the Page Upper Directory and the Page Middle Directory by setting the number of entries in them to 1 and mapping these two entries into the proper entry of the Page Global Directory.  For 32-bit architectures with the Physical Address Extension enabled, three paging levels are used.

As a general rule, the Linux kernel is installed in RAM starting from the physical address 0x00100000 i.e., from the second megabyte. The total number of page frames required depends on how the kernel is configured. A typical configuration yields a kernel that can be loaded in less than 3 MB of RAM.


The linear address space of a process is divided into two parts:
  • Linear addresses from 0x00000000 to 0xbfffffff can be addressed when the process runs in either User or Kernel Mode.
  • Linear addresses from 0xc0000000 to 0xffffffff can be addressed only when the process runs in Kernel Mode.
The content of the first entries of the Page Global Directory that map linear addresses lower than 0xc0000000 (the first 768 entries with PAE disabled, or the first 3 entries with PAE enabled) depends on the specific process. Conversely, the remaining entries should be the same for all processes and equal to the corresponding entries of the master kernel Page Global Directory

The kernel maintains a set of page tables for its own use, rooted at a so-called master kernel Page Global Directory.  the highest entries of the master kernel Page Global Directory are the reference model for the corresponding entries of the Page Global Directories of every regular process in the system.

a fix-mapped linear address is a constant linear address like 0xffffc000 whose corresponding physical address does not have to be the linear address minus 0xc000000, but rather a physical address set in an arbitrary way.

总结

这是阅读《深入理解Linux内核》第二章之后总结的一些东西,我再用自己的话总结一下。

在Linux中段的作用已经很小了,在硬件上下文中CPU的寄存器全部保存到进程的task_stuct结构体的thread中,所以每个CPU只有一个TSS!而前面看到段的初始地址均为0,即逻辑地址与物理地址相一致,简化了地址转化的复杂度。段寄存器的作用,一是提供段操作符的位置,第二就是特权级。

Linux中更侧重的是页的使用。32位和64位系统中采用的页表级数不同,但是可兼容。进程的理论可寻址为4G,但是内核占据了最后的1G空间,所以进程可以使用的实际上为3G,这也是我们为什么看到在32位系统上看到4G的物理内存却显示的3G。每个进程的最后1G的页表映射都是一样的,即逻辑地址减去3G就是物理地址,内核占据内存的1G空间,但是不一定使用它(可能Present位为0)。在《深入理解Linux内核》中对物理内存的大小不同,各自分析了不同的分配方式。另外内核的1G空间其实只能用896M,后面的128M是保留的,称为fix-mapped linear address。这段空间可以映射到物理内存的任何地方,即和内核内存的896MB只能映射到物理内存的前段是不一样的。



想更详细的了解Linux内存,请看一看 http://blog.csdn.net/dog250/article/details/16356141,写的很好,赞一个!


参考:《深入理解Linux内核》第三版



原创粉丝点击