Intel X86 32位CPU内存管理

在X86系列中,8086和8088是16为处理器,而从80386开始为32为处理器,80286则是该系列从8088到80386,也就是16位处理器到32位处理器的一个过渡。

段式内存管理

Intel决定在16位CPU,也就是8086CPU,中使用1M的内存空间,地址总线的宽度也就为20位,但是CPU的ALU(算术逻辑单元)的宽度只有16位,因此采用了“分段”的设计方法。

Intel在8086CPU内置了四个段寄存器:CS,DS,SS和ES,分别用于可执行代码既指令、数据、堆栈和其它。每个段寄存器是16位的,对应于地址总线的高16位。在汇编语言中,访问一个内存的位置使用ES:AX这样的语句,实际访问的位置为 ES*2^4+AX处。这样完成了16位内部地址到20位实际地址的转换。

这种方式没有地址空间的把保护机制,用来改变段寄存器内容的指令不是什么”特权指令“,而就是MOV,因此进程可以随意修改段寄存器,从而访问整个内存空间的内容。这种缺乏对内存空间保护的内存寻址模式被称为 实模式,与保护模式对应。

针对8086的缺陷,Intel从80286开始实现保护模式。同时,不久之后32位的80386CPU也研发成功了。从80386之后Intel的CPU历经80486、Pentium、Pentium Ⅱ等型号,虽然速度提升,但是结构并无重大改变,因此统称i386CPU。下面介绍i386系列的保护模式。

Intel选择了再段寄存器的基础上构筑保护模式的构思,并且保留段寄存器为16位(这样才可以利用原来的四个寄存器),但是又增添了2个新的段寄存器FS和GS。基本思路为:在保护模式下改变段寄存器的功能,使其从一个单纯的基地址(变相的基地址)变成指向这样一个数据结构的指针。这样,当一条访问内存指令发出一个内存地址时,CPU就可以这样归纳出实际应放上总线的地址:

  1. 根据指令的性质来确定应该使用哪一个段寄存器,例如转移指令中的地址在代码段(CS),而取数指令中的代码在数据段(DS),这一点和实模式相同。

  2. 根据段寄存器的内容,找出相应的”地址段描述结构“。

  3. 从地址段描述结构中的到基地址。

  4. 将指令中发出的地址作为位移,与段描述结构中规定的长度相比,查看是否越界。(保护模式)

  5. 根据指令的性质和段描述结构中的访问权限来确定是否越权。

  6. 将指令中的地址作为位移,与基地相加得出实际的“物理地址”。

在80386CPU中增加了2个寄存器,全局性的段描述表寄存器GDTR,和局部性的段描述表寄存器LDTR。访问这两个寄存器的指令被设置为专有指令,起到了保护作用。段寄存器的高13为用作访问段描述表中具体描述结构的下标。


每个段描述表项的大小是8字节,每个描述表项含有段的基地址和段的大小,在加上其他的一些信息。

B31--B24表示基地址(base)的高8位,B23-B0表示基地址的地24位。因为在一开始的实际中,Intel是采用了24位地址线,后来又改为32位地址。L19--L16 和 L15--L0表示段长,DPL是个2位的位段,代表访问本段需要的特权。

在80386的段内存管理的基础上,如果把每个段寄存器都指向同一个描述项,而将该描述项的基地址设为0,并将段长度设为最大,这样便形成了从0开始覆盖整个32位地址空间的一个整段,此时物理地址与逻辑地址相同。因为32位CPU的寄存器也为32位,可以对整个32位内存寻址。

i386的页式内存管理机制

因为在之前的设计中保护模式依赖于段式管理,所以Intel决定在段式内存的机制之上实现页式内存管理。80386把线性地址空间划分为4K字节的页面,每个页面可以被映射为物理存储空间中任意一块4K字节大小的空间(边界必须与4K字节对齐)。

由于页式管理的引入,对32位线性地址有了新的解释(以前就是物理地址):

可以看出,在页面目录中共有$2^{10}=1024$个目录项,每个目录项指向一个页面表,而每个页面表又共有1024个页面描述项。类似于GDTR和LDTR,又增加了一个新的寄存器CR3作为指向当前页面目录的指针,这样,从线性地址到物理地址的映射为:

  1. 从CR3取得页面目录的基地址。
  2. 以线性地址中的dir位段(22-31)为下标,在目录中取得相应页面表的基地址。
  3. 以线性地址中的page(12-21)位段为下标,在所得到的页面表中取得相应的页面描述项。
  4. 将页面描述项中的基地址与线性地址中的offset段相加,获得物理地址。

采用目录加页表的双层机制是处于节省空间的考虑。这样,我们只需留出必要的1024个目录项的空间,而没有被下使用的页表可以不创建。而如果采用单层记录,则需要留出必要的1024*1024个页表的空间,因为目录和页表都是基于偏移量来寻址的,必须留出整个数组的空间。

如前所述,目录项中含有一个指向页表的指针,而页表项中含有指向一个页面其实地址的指针。由于页面表和页面的起始位置总是在4K的边界上,所以低12位一定为0。这样,目录项和页表项中只要用20为用于指针就可以了。

Intel X86 32位CPU内存管理----《Linux内核源码情景分析》笔记(一)的更多相关文章

  1. Linux 内核源码情景分析 chap 2 存储管理 (四)

    物理页面的使用和周转 1. 几个术语 1.1 虚存页面 指虚拟地址空间中一个固定大小, 边界与页面大小 4KB 对齐的区间及其内容 1.2 物理页面 与虚存页面相对的, 须要映射到某种物理存储介质上面 ...

  2. Linux内核源码情景分析-wait()、schedule()

    父进程执行wait4,并调用schedule切换到子进程: wait4(child, NULL, 0, NULL); 像其它系统调用一样.wait4()在内核中的入口是sys_wait4().代码例如 ...

  3. Linux内核源码情景分析-系统调用

    一.系统调用初始化 void __init trap_init(void) { ...... set_system_gate(SYSCALL_VECTOR,&system_call);//0x ...

  4. Linux内核源码分析方法

    一.内核源码之我见 Linux内核代码的庞大令不少人“望而生畏”,也正因为如此,使得人们对Linux的了解仅处于泛泛的层次.如果想透析Linux,深入操作系统的本质,阅读内核源码是最有效的途径.我们都 ...

  5. 【转】Linux内核源码分析方法

    一.内核源码之我见 Linux内核代码的庞大令不少人“望而生畏”,也正因为如此,使得人们对Linux的了解仅处于泛泛的层次.如果想透析Linux,深入操作系统的本质,阅读内核源码是最有效的途径.我们都 ...

  6. Linux内核源码分析方法_转

    Linux内核源码分析方法 转自:http://www.cnblogs.com/fanzhidongyzby/archive/2013/03/20/2970624.html 一.内核源码之我见 Lin ...

  7. Linux内核源码分析 day01——内存寻址

    前言 Linux内核源码分析 Antz系统编写已经开始了内核部分了,在编写时同时也参考学习一点Linux内核知识. 自制Antz操作系统 一个自制的操作系统,Antz .半图形化半命令式系统,同时嵌入 ...

  8. Linux内核源码特殊用法

    崇拜并且转载的: http://ilinuxkernel.com/files/5/Linux_Kernel_Source_Code.htm Linux内核源码特殊用法 1 前言 Linux内核源码主要 ...

  9. linux内核源码注解

    轻松学习Linux操作系统内核源码的方法 针对好多Linux 爱好者对内核很有兴趣却无从下口,本文旨在介绍一种解读linux内核源码的入门方法,而不是解说linux复杂的内核机制:一.核心源程序的文件 ...

随机推荐

  1. .net持续集成测试篇之Nunit参数化测试

    系列目录 在进行单元测试的时候,很多时候,很多时候我们都是在单元测试方法内部提供特定的值,但是这样测试往往造成样本数不足从而导致覆盖的结果不够全面,很多时候我们更想提供来自外部的,满足条件的一组值来进 ...

  2. 2019牛客多校训练第三场B.Crazy Binary String(思维+前缀和)

    题目传送门 大致题意: 输入整数n(1<=n<=100000),再输入由n个0或1组成的字符串,求该字符串中满足1和0个数相等的最长子串.子序列. sample input: 801001 ...

  3. 关于Linux的简单介绍

    Linux: 诞生日期:1991年 开发者:林纳斯·托瓦茨 特点:免费,开源    发行版本:centos|red Hat|Ubuntu|红旗等    思想:一切都是文件 重要文件目录 bin:二进制 ...

  4. python 函数和函数名的应用

    一.函数 1.函数定义 def 关键字 -- 定义 func 函数名 -- 和变量定义规则一样 ()必须要写格式 : 声明语句结束 def my_len(): ​ 函数体 def func(a:int ...

  5. 调用链系列(3):如何从零开始捕获body和header

    拓展阅读:调用链系列(1):解读UAVStack中的贪吃蛇 调用链系列(2):轻调用链实现 在Java中,HTTP协议的请求/响应模型是由Servlet规范+Servlet容器(如Tomcat)实现的 ...

  6. 史上最全面 Android逆向培训之__实战(hook微信)

    我的CSDN博客:https://blog.csdn.net/gfg156196   by--qihao 书接上文,上回说到了xposed,接下来就用一下,体验一下商业项目的赶脚…… 上一篇:史上最全 ...

  7. 在centos6系列vps装Tomcat8.0

    In the following tutorial you will learn how to install and set-up Apache Tomcat 8 on your CentOS 6 ...

  8. js中toFixed精度问题的解决办法

    toFixed() 方法可把 Number 四舍五入为指定小数位数的数字.例如将数据Num保留2位小数,则表示为:toFixed(Num):但是其四舍五入的规则与数学中的规则不同,使用的是银行家舍入规 ...

  9. luoguP2444_[POI2000]病毒

    题意 给定多个01模式串,问是否存在一个无限长的字符串不包含任何一个模式串. 分析 好像数据有点水,网上一大堆题解连样例都没过??? 多模式串,先把AC自动机建出来再说. 反向考虑,若存在一个无限长的 ...

  10. 常用Feed流架构实现

    业务中很多需求都会用到类似feed流的架构. 例如 微信朋友圈 微博 动态 1对N消息. 一般feed流的架构实现有下面几种. 假如现在的业务场景是微博,然后当前的数据情况是: 用户A关注了用户B和C ...