免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 772 | 回复: 0
打印 上一主题 下一主题

[内核入门] Intel i386 CPU(页式内存管理) [复制链接]

论坛徽章:
13
15-16赛季CBA联赛之八一
日期:2016-07-08 21:00:1415-16赛季CBA联赛之同曦
日期:2017-02-15 14:26:1515-16赛季CBA联赛之佛山
日期:2017-02-20 14:19:2615-16赛季CBA联赛之青岛
日期:2017-05-07 16:49:1115-16赛季CBA联赛之广夏
日期:2017-07-30 09:13:1215-16赛季CBA联赛之广东
日期:2018-07-05 22:34:3615-16赛季CBA联赛之江苏
日期:2018-09-03 12:10:2115-16赛季CBA联赛之上海
日期:2018-09-25 03:49:2215-16赛季CBA联赛之广东
日期:2018-09-25 04:09:12
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2016-09-15 15:54 |只看该作者 |倒序浏览
  • i386段式映射过程
    例如:汇编语句“mov %dx, 0x12345678”(AT&T格式,机器码:“66 89 14 25 78 56 34 12”),并假设CPU执行到这条机器指令时,CS段寄存器值为0x0003(段描述符表下标:0;TI:0,使用全局描述符表;RPL:3,当前进程权限最低)。
    ① CPU根据CS寄存器的值,从全局描述符表的0号下标,找到进程当前段的描述符,假设如下:
        
    ② 进行越界检查、权限检查等,从这个描述符看,它描述的是一个从0开始,长度为4G的段,并且访问权限要求最低,所以CPU就顺利通过了检查
    ③ 段基址0+逻辑地址0x12345678 → 线性地址0x12345678

    上篇文章中提到过,CPU对段式映射的支持,是为了向前兼容才保留的,并且Intel攻城狮为了节约CPU资源,保护模式的实现仍然利用了段寄存器资源,总之就是程序中的地址必须先要经过段式映射,内核即使选择用页式内存管理,仍然要为段式映射做好设置,至少保证CPU别在段式映射检查阶段出错,导致指令执行不了。
    如果纯粹使用段式内存管理,很容易理解,每个进程一般都有多个段描述符表,放在内存不同的位置,当切换到该进程时,LDTR也会跟随着指向该进程的段描述符表,每个描述符确确实实的将整个内存“切割”成一段一段的,比如段基址0x80000、段长度1MB。

  • i386页式映射过程

    Linux内核采用的就是页式内存管理,所以它建立的段描述符就跟上述举的例子一样,段基址为0,段长度为4G,并且实际只建立了4个描述符,分别用于描述“内核空间代码段”、“内核空间数据段”、“用户空间代码段”、“用户空间数据段”,都放在全局描述符表里。这样,内核在创建用户进程时,将进程段寄存器镜像的下标设置正确、TI设置为0、RPL设置为3,保证CPU在执行这些进程的指令时,段式映片阶段不可能出现越界、越权等错误。总之,Linux内核对于段描述符的这种设置方式,就是不需要它真正起到映射作用,逻辑地址经过段式映射得到的线性地址,值保持不变(这已经是软件层面的知识,后面还会学习)。


    理解“线性地址→物理地址”映射过程(本文目标
    80386对于线性地址的含义设计如下:
   
    然后分别用页目录索引、页面索引,根据内核设置的页目录表、页面表,找到该地址所在的页面,再加上页内偏移,得到最终的物理地址:
   

    为什么映射要分两步,比如为什么为直接把目录索引和页面索引合并为一个索引?
    分两步相当于把一张大纸分成很多小纸,很多进程需要的内存很少,需要记录的映射关系自然也少,用一张很大的纸记就会很浪费。

    页式内存管理比段式内存管理优势在哪?
    ① 页大小一般固定为4K,而段的长度不确定,不方便维护;
    ② 段如果太小,一方面,在一个大程序里,段描述符可能就不够用了;另一方面,高速缓存中的段描述符经常失效,必须去内存读,浪费了效率。而如果段比较大,如果物理内存被分配的零零碎碎了,较大的段可能就分配不成功,而且与交换分区的换出/换入的代价也比一页高的多。

    自行车厂商组装出自行车这样一种硬件结构,初衷是为了让你向前登,带动后轮旋转,但完全也可以摆在房间里反方向登,当作健身器材用。所以说软件可以根据硬件的特性灵活使用,硬件只提供机制,那么段式映射、页式映射过程中依赖的段描述符表、页目录表、页表这些东西,内核都是什么时候进行设置的呢?
    ① 系统启动在进入保护模式前,为构建一个临时的页目录表、页表;
    ② 内核创建进程时,为这个进程创建基本的目录项、表项;
    ③ 程序执行过程中动态分配/释放内存,通过分配函数进入内核时,内核动态修改该进程的目录表、页表。

    到此为止,关于内存管理的硬件设计已经介绍完了,其实就是要理解“逻辑地址→线性地址→物理地址”的映射过程中,硬件做了什么,就已经达到目的,而不用理解电路是怎么做到的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP