操作系统实战 45 讲
彭东
网名 LMOS,Intel 傲腾项目关键开发者
65203 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 60 讲
尝尝鲜:从一个Hello到另一个Hello (2讲)
特别放送 (1讲)
操作系统实战 45 讲
15
15
1.0x
00:00/00:00
登录|注册

06 | 虚幻与真实:程序中的地址如何转换?

操作系统如何对应用程序的地址空间进行隔离
x86 CPU上的MMU
MMU的作用和实现方式
虚拟地址与物理地址的分离
多道程序运行的问题
MMU地址转换失败的处理流程
开启MMU的步骤
2MB页的分页方式
4KB页的分页方式
4MB页的分页方式
4KB页的分页方式
MMU页表的实现
MMU的工作原理框架图
分页模型的实现方式
MMU(内存管理单元)的作用
内存只认物理地址
物理地址在逻辑上是一个数据
虚拟地址的独立性和统一性
虚拟地址空间的定义由链接器处理
虚拟地址的逻辑存在
问题4: 多程序并发对内存方案的影响
问题3: 解决内存容量问题
问题2: 程序A和程序B不会互相读写各自的内存空间
问题1: 程序A和程序B没有内存地址的冲突
思考题
重点回顾
MMU地址转换失败
开启MMU
长模式下的分页
保护模式下的分页
MMU
虚拟地址到物理地址的转换
物理地址
虚拟地址
从一个多程序并发的场景说起
虚幻与真实:程序中的地址如何转换?

该思维导图由 AI 生成,仅供参考

你好,我是 LMOS。
从前面的课程我们得知,CPU 执行程序、处理数据都要和内存打交道,这个打交道的方式就是内存地址。
读取指令、读写数据都需要首先告诉内存芯片:hi,内存老哥请你把 0x10000 地址处的数据交给我……hi,内存老哥,我已经计算完成,请让我把结果写回 0x200000 地址的空间。这些地址存在于代码指令字段后的常数,或者存在于某个寄存器中。
今天,我们就来专门研究一下程序中的地址。说起程序中的地址,不知道你是否好奇过,为啥系统设计者要引入虚拟地址呢?
我会先带你从一个多程序并发的场景热身,一起思考这会导致哪些问题,为什么能用虚拟地址解决这些问题。
搞懂原理之后,我还会带你一起探索虚拟地址和物理地址的关系和转换机制。在后面的课里,你会发现,我们最宝贵的内存资源正是通过这些机制来管理的。

从一个多程序并发的场景说起

设想一下,如果一台计算机的内存中只运行一个程序 A,这种方式正好用前面 CPU 的实模式来运行,因为程序 A 的地址在链接时就可以确定,例如从内存地址 0x8000 开始,每次运行程序 A 都装入内存 0x8000 地址处开始运行,没有其它程序干扰。
现在改变一下,内存中又放一道程序 B,程序 A 和程序 B 各自运行一秒钟,如此循环,直到其中之一结束。这个新场景下就会产生一些问题,当然这里我们只关心内存相关的这几个核心问题。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入探讨了计算机系统中的地址转换概念,重点关注了虚拟地址和物理地址之间的关系以及转换机制。在多程序并发的情况下,引入虚拟地址解决了地址冲突、内存空间隔离和内存容量等核心问题。文章详细介绍了内存管理单元(MMU)的作用,以及页表在虚拟地址到物理地址转换中的重要性。此外,还对保护模式下的分页和长模式下的分页进行了深入讨论,包括不同分页模式下的虚拟地址结构、页表结构和地址转换过程。通过本文的介绍,读者可以快速了解程序中地址转换的原理和机制,以及在x86 CPU上的具体实现细节。文章内容详实,适合对计算机系统地址转换感兴趣的读者阅读。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《操作系统实战 45 讲》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(103)

  • 最新
  • 精选
  • 一省吾身
    置顶
    信息量爆炸,细节深挖不动,大方向上的个人理解和收获: 为什么需要虚拟地址: 实模式中如果运行多道程序有一些问题需要解决: 地址冲突 控制互相访问 代码占用的空间大到物理内存放不下怎么办 不同计算机的容量各不相同,方案如何全部支持 给每个程序一个私有的连续的独立的虚拟的地址空间,和计算机无关,和其它程序无关. 解决思路: 将虚拟地址与物理地址分离,让应用程序从实际的物理内存中解耦出来,增加中间层MMU去做地址转换,对程序透明. MMU: 设计思路: 虚拟地址到物理地址直接做映射,则映射关系大到无法接收,维护成本太高. 虚拟段基址映射到物理段基址,看似可以,但是段长度各不相同,并且粒度可能会很大. 因此把虚拟地址和物理地址空间都分成同等大小的块,按照虚拟页和物理页进行映射和转换,地址转换表中存放虚拟页地址对应的物理页地址即可. 实现思路: 纯硬件实现没有灵活性,用软件实现太低效,因此使用软硬件结合的方式. 用硬件电路逻辑实现地址转换器件,接受虚拟地址和地址关系转换表,输出物理地址. 为什么需要多级页表: 每个进程都有自己的页表,多级页表可以省掉大量未映射页表占用的空间,为null则说明后面的页都没有使用. 虚拟地址由虚拟页号和虚拟页号偏移组成,多级页表查找时可以使用索引.

    作者回复: 嗯嗯 理解的不错

    2022-05-06
    4
  • Geek_4b6813
    置顶
    配合之前的现代操作系统的学习有一些收获不知道对或不对 虚拟内存实际上是存储器地址空间抽象的一种实现。从进程的角度看起来就好像自己独占了整个内存,链接器链接编译产物的时候只需要从0地址开始做变量和函数地址的替换,不需要关心自己是否会把其他进程的内存单元给污染。地址空间是进程可以访问的所有内存单元的集合 而虚拟内存的实现带来的好处只要有 1.利用程序的局部性原理,使用时间换空间,通过不断地淘汰/加载页表项就可以模拟出巨大的内存。 2.使用mmu并行计算的能力,减少了基址寄存器和界限寄存器的add和compare操作。 但是软件开发是没有银弹的,虚拟内存同时也带来了一些实现上的挑战 1.从虚拟内存到物理内存的映射必须要尽可能快,不然访存的时候反而会成为指令执行速度的瓶颈,这点现代操作系统大多通过在内核中维护一个tlb做页表-页框的映射缓存表来实现,这里是空间换时间。 2.随着虚拟内存的增加,比如要表示4GB的虚拟内存,以4KB的页面大小为例,共需要4GB/4KB= 2^20,而每个页表项需要32位即是4个字节大小,一个进程的页表总共为2^20*4 = 4194304(字节) = 4MB。 假设4核cpu同时运行不同的进程,操作系统在内核中至少需要维护16MB的页表。看起好像很小对不对,大家可以尝试按64位内存总线去换算。所以为了避免一次性加载大量页表到内存中,会采用多级页表策略。如老师文中描述的,一次只加载一级页表到内存中,并且可以选择淘汰上一级页表,通过多次映射的方法来避免大页表,到这里又是时间换空间了。 而对于老师说的,mmu无法映射物理地址时,有几种原因 1.访问了受内核保护的页面,或者访问了只读的页面(比如c语言中存储字符串字面量和const变量的段),此时内核会抛出段错误 2.页面和页框没有产生映射关系,但是数据页已经被其他进程加载到内存中了,此时只需要建立页面和页框的映射关系,称为次级缺页中断 3.页面和页框没有产生映射关系,数据页也没有被加载到内存中(在磁盘上),此时需要发生磁盘io从磁盘中加载页到内存中,还需要建立页面和页框的映射关系,称为严重缺页中断。 除了第一点,第二第三都会以内核降低自身运行速度来修复,也就是老师说的,通过中断形成页表映射,然后再重新执行引起中断的命令(此时数据页已经在内存中并且建立映射关系了)。

    作者回复: 是的,大写6666,太厉害了

    2021-06-26
    8
    93
  • 宇宙的琴弦
    置顶
    看同学们的评论,也让人收获不少,喜欢这样的氛围!感谢!

    作者回复: 谢谢,希望以我的微薄技术能帮到大家

    2021-05-22
    12
  • pedro
    置顶
    😃又是信息量爆炸的一节,不过读下来也是挺爽的。这里我替很多同学说明一下,虚拟地址中的页内偏移才是决定页大小和多级目录的核心点,页内偏移必须与页大小保持一致,这样才能保证寻址可以找到页内的每一个地址。 对于思考题,其实也比较简单,文中也谈到了,实模式下多个任务共享所有地址空间太危险,因此才有了保护模式,保护模式下的分页模式是一个巨大的创新。 对于每个进程而言,它会误认为(被操作系统欺骗)自己独有所有地址空间,因此它访问地址是不会考虑任何问题的,可是这个地址是虚拟地址,待被MMU翻译后会得到对应的页表,而这个页表由操作系统管理,不同的进程拥有不同的页表,也因此产生了进程地址空间隔离,但是多个进程也是可以共享某个页表,这也是进程通信(IPC)的根本手段。

    作者回复: 你学到位了 66666

    2021-05-21
    21
    137
  • blentle
    多个进程隔离应该是操作系统进行任务切换时会改写CPU的页表基地址寄存器为当前被运行进程的页表基地址吧!

    作者回复: 是的 是的

    2021-05-21
    3
    32
  • 一脸懵逼的进来,一头雾水的出去

    作者回复: 不要着急 等后面的课程出来了 就明白了

    2021-05-21
    5
    27
  • springXu
    每一个进程会有不同的页表内容。 在32位的windows系统中虚拟地址2g到4g空间都是系统函数调用空间,这部分的对应的物理空间是同一块区域。但低端虚拟内存空间各个进程空间对应的物理地址不相同,所以进程间的页表有部分相同,有部分是不同的。 另外32位的xp系统是可以设置成1g的系统内存空间的,也就是进程的私有空间由0到2g的范围变成了0到3g的虚拟空间。与上面的描述又有些变化了。 到了64位好像是128T的虚拟内存空间的是进程私有虚拟内存空间。

    作者回复: 你说的对 6666

    2021-05-21
    4
    10
  • Geek_9627ff
    这课也太顶了吧,撒哈拉沙漠都没这课干

    编辑回复: 写操作系统,有一些硬核的硬件知识必须补补课,加油加油~

    2021-08-28
    8
  • xzy
    有个疑问,现代CPU都是多核的,那么一个4核的CPU是共享一个MMU,还是每个核心都有自己的MMU,有4个MMU呢?

    作者回复: 都 有自己的

    2021-08-07
    4
    8
  • Paul Shan
    思考题 每个程序对应的CR3内容不同,进而映射也不相同,同样的虚拟地址被映射到不同的物理地址。

    作者回复: 你好。正确 正确

    2021-05-23
    2
    8
收起评论
显示
设置
留言
99+
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部