当使用Inter 80x86微处理器时,必须区分三种地址:
逻辑地址:有段基址和段偏移量组成。
线性地址:32位无符号整数。
物理地址
CPU通过分段单元将逻辑地址转换为线性地址,再通过分页单元将线性地址转化为物理地址
硬件的分段单元
从80386CPU开始,Intel微处理器能执行两种不同的地址转换模式,分别称为实模式(为了与早期OS兼容)和保护模式,这里重点放在保护模式上。
段寄存器
一个逻辑地址由两部分组成,一个段标识符(16位)和一个相对地址的偏移量(32位),段寄存器是用来存放段选则符的,包括cs,ss,ds,es,fs,gs。
cs:代码段寄存器,用于存放程序指令的段。
ss:栈段寄存器,指向当前存放程序栈的段;什么是程序栈空间,即主要用来 存放函数和数组等。
ds:数据段寄存器,指向存放静态数据(永久性不变的数据)或者外部数据的段。
其它三个寄存器做一般用途,可以用来访问任意段。
cs寄存器还有一个两位域,用来指明cpu的特权级,linux中只有0和3级,分别为内核态和用户态。
段描述符
占8字节,段描述符被放在全局描述符表(GDT)或者局部描述符表(LDT)。
系统通常只定义一个GDT(其地址被存放在GDTR寄存器中),每个进程可以有自己的LDT(其地址被存放在LDTR寄存器中)。
其中,系统段存储内核数据结构,任务状态段用于保存处理器寄存器的内容。
段选择符
为了加速逻辑地址到线性地址的转换,Intel处理器提供一种附加的非编程的寄存器(不能被程序员设置),这样在访问段寄存器中段选择符时,就不能(不需要)访问GDT或LDT了。
段单元
逻辑地址转化为线性地址总览:
Linux中的段
Linux更喜欢分页的方式,当所有的进程使用相同的段寄存器值时,内存管理变得更简单,它们能共享相同的线性地址。而且许多RISC处理器不支持段功能,Linux不好做移植。
硬件的分页单元
分页单元认为所有的RAM被分成固定长度的页框,每一个页框包含一页。在Intel处理器中,通过设置CR0寄存器的PG标志启动分页。当PG=0时,线性地址就被解释成物理地址。
常规分页
从i80386起,Intel处理器的分页单元处理4KB的页。32位线性地址被分成三个域:目录(10),页表(10),偏移量(12)。
正在使用的页目录表的物理地址存放在处理器的CR3寄存器中。
这里要说明下,在页目录和页表表项中由Page Size标志为1,页目录项指的是4MB的页框。如果Present为0,分页单元就把这个线性地址存放在处理器的CR2寄存器中,并产生14号缺页异常。
扩展分页
从奔腾处理器开始,Intel 80x86微处理器引进了扩展分页,它允许页框大小为4KB或4MB(页目录10位,偏移量22位)。
之后就是引入cache和TLB(计算机组成原理内容),就不详细说了。
Linux的分页
Linux采用三级分页,页全局目录(10),页中间目录(10),页表(10),偏移量(13)。
保留的页框
内核代码和数据结构存放在一组保留的页框中,这些页框所含的页从不动态分配或者交换到内存中。
作为一条常规,Linux内核被安装在RAM物理地址0x00100000开始的地方,为什么从这个地方开始?
因为页框0由BIOS使用,存放硬件配置。
物理地址0x000a0000到0x000fffff被BIO程序使用同时映射ISA上的显存。
前1MB的其它页框可能被保留用作特定的计算机模式。
为了避免把内核装入一组不连续的页框,Linux更愿跳过第1MB的RAM。(内核小于1MB _text---_etext)
审核编辑:刘清
全部0条评论
快来发表一下你的评论吧 !