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

20 | 土地需求扩大与保障:如何表示虚拟内存?

初始化进程的用户空间
初始化mmadrsdsc_t结构
页面盒子管理
虚拟地址区间和物理内存页面映射
进程的虚拟地址空间
页面盒子的头数据结构
页面盒子数据结构
进程的内存地址空间数据结构
整个虚拟地址空间描述数据结构
虚拟地址区间数据结构
Cosmos虚拟地址空间划分
x86 CPU虚拟地址空间划分
思考题
初始化
数据结构关系
数据结构设计
虚拟地址空间划分
虚拟内存

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

你好,我是 LMOS。
在现实中,有的人需要向政府申请一大块区域,在这块区域中建楼办厂,但是土地有限且已经被占用。所以可能的方案是,只给你分配一个总的面积区域,今年湖北有空地就在湖北建立一部分厂房,明年广东有空地就在广东再建另一部分厂房,但是总面积不变。
其实在计算机系统中也有类似的情况,一个应用往往拥有很大的连续地址空间,并且每个应用都是一样的,只有在运行时才能分配到真正的物理内存,在操作系统中这称为虚拟内存。
那问题来了,操作系统要怎样实现虚拟内存呢?由于内容比较多,我会用两节课的时间带你解决这个问题。今天这节课,我们先进行虚拟地址空间的划分,搞定虚拟内存数据结构的设计。下节课再动手实现虚拟内存的核心功能。
好,让我们进入正题,先从虚拟地址空间的划分入手,配套代码你可以从这里获得。

虚拟地址空间的划分

虚拟地址就是逻辑上的一个数值,而虚拟地址空间就是一堆数值的集合。通常情况下,32 位的处理器有 0~0xFFFFFFFF 的虚拟地址空间,而 64 位的虚拟地址空间则更大,有 0~0xFFFFFFFFFFFFFFFF 的虚拟地址空间。
对于如此巨大的地址空间,我们自然需要一定的安排和设计,比如什么虚拟地址段放应用,什么虚拟地址段放内核等。下面我们首先看看处理器硬件层面的划分,再来看看在此基础上我们系统软件层面是如何划分的。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文介绍了虚拟内存在计算机系统中的重要性以及其实现方式。作者通过对现实中土地需求扩大与保障的类比,引出了虚拟内存的概念,并详细介绍了在计算机系统中如何表示虚拟内存,包括虚拟地址空间的划分和相关数据结构的设计。文章突出了虚拟内存在操作系统中的核心功能,以及设计的数据结构之间的关系。此外,还介绍了虚拟地址空间的划分和初始化工作。整体而言,本文对虚拟内存的概念及其在操作系统中的具体应用进行了详细阐述,对于想深入了解计算机系统内存管理的技术人员具有一定的参考价值。

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

全部留言(12)

  • 最新
  • 精选
  • 二三子也
    内核代码使用虚拟地址,但是内核有时需要用到物理地址,比如设置页表项等。线性映射区使得内核能通过加减一个固定值的方式,方便的完成虚拟地址与物理地址的转换。

    作者回复: 你好 , 正确的

    2021-06-23
    17
  • pedro
    0xFFFF800000000000~0xFFFF800400000000 的线性映射区是MMU 页表映射数据,保存虚拟地址和物理地址之间的映射关系,没有这块区域,CPU无法在长模式下工作,通过虚拟地址将无法访问真实的数据。 且这个区域必须在内核态,放在用户态太危险了,万一被某个应用程序修改,直接爆炸。

    作者回复: 也是正确的,大写6666

    2021-06-23
    2
    11
  • 菜鸟
    关于内存的分配与管理定义了大量的数据结构,这些数据结构是借鉴的Linux,还是自己创建的?

    作者回复: 当然是自己创建的!为什么要用Linux的? Linux的有些东西不错,但是有些东西不行。

    2021-08-04
    5
  • 青玉白露
    这个线性映射区主要是用来存放MMU的 试想,如果所有的地址都是物理地址转换到虚拟地址,这个转换关系存在哪?存在虚拟内存里?那这不是套娃么,你连MMU都找不到,根本没法转换。 所以才有了一段映射区,内核态直接去访问这个区域就可以获取MMU的数据,避免套娃。

    作者回复: 是的 哈哈

    2021-07-13
    4
  • Feen
    最后的思考题:因为不管是实模式还是保护模式或者长模式,物理内存 0~0x400000000的实体空间是被系统的启动类型文件占用,这里不止包括内核相关的,还有BIOS中断表等等前面课程讲过的硬软件系统必须要的文件,开机就占用,关机谁也占用不了,首先给这段物理地址就固定下来。这是必要的。 而操作系统运行在非实模式下虚拟地址空间之后,如果不建立线性映射表,那对这块物理地址时不安全的,就如同实模式切换到保护模式为什么增加了各种检查和权限一个道理,也需要虚拟地址与物理地址有一个线性和固定的映射表,保护此段物理内存上的的文件,告知操作系统在分配内存的时候避开雷区。就如同隔着墙货架上抓东西,你可以抓货架上的任何东西,但要是抓到货架的框子,使劲一抓,可以想象到什么后果。 另外0xFFFF800000000000~0xFFFF800400000000的地址数值时可以变的,比如改成0xFFFF800400000000~0xFFFF800800000000,还可以改成其他,只要按照这里的规则和做好映射关系就可以,当然选择0xFFFF800000000000~0xFFFF800400000000对应0x0~0x400000000更符合人的阅读习惯。

    作者回复: 嗯 嗯

    2021-07-10
    3
  • │.Sk
    老师好,请问我下面的理解对吗? 1. 在 init_kvirmemadrs 函数中,初始化完 initmmadrsdsc 及相应的 userspace 虚拟内存地址区间后;调用了 hal_mmu_init 方法 2. 在 hal_mmu_init 方法中复制了在内核初始化时设置的顶级页目录到 mmu->mud_tdirearr,并把顶级页目录的第 0 项清空(我理解此处是为了清除原来该处映射到内核空间的项,改为未映射,这样访问用户空间的虚拟地址时候会触发 page fault,再分配实际的物理页并映射) 3. 在 hal_mmu_init 执行完后,紧接着执行了 hal_mmu_load 函数,该函数会把 mmu->mud_tdirearr 转换为物理地址设置到 cr3;该步骤执行完后,访问 0~0x400000000 的地址会触发 pagefault 4. 在执行完 init_kvirmemadrs 后,cosmos 代码还有许多访问内核全局变量(如 osdevtable 等)代码,这些变化是定义在内核文件的 .data 段中的,是不是因为内核文件链接脚本用了如下定义 .data ALIGN(4) : AT(ADDR(.data)-VIRTUAL_ADDRESS) { *(.data) *(.bss) },所以可以让这些内核全局变量的加载到物理地址 0~0x400000000 中,但是代码中直接访问这些内核全局变量实际上用的是 0xffff800000000000~0xffff800400000000 中的虚拟地址,这样才会在顶级页目录的第 0 项被清空后访问内核全局变量不会造成 page fault

    作者回复: 正确 正确

    2022-10-17归属地:湖北
  • 艾恩凝
    打卡,再重新梳理一遍

    作者回复: 加油,

    2022-04-20
  • ifelse
    各位大神666

    编辑回复: 坚持学习和分享,将来别人也会为你刷666~

    2022-02-15
  • 沈畅
    课后题目我再补充一点,本节为虚拟内存管理创建的一系列结构,需要进行内存分配(调用了内存对象分配接口),0xFFFF800000000000~0xFFFF800400000000 地址空间,之前已经在MMU建立了地址映射,为内核分配内存,使用内存的必要条件。否则内核无法使用内存了。

    作者回复: 是的

    2021-09-20
  • 相逢是缘
    一直有一个疑问,应用空间和内存空间有各自的页表,虚拟内存为什么要划分为用户空间和内核空间呢,有什么作用呢?内核空间和应用空间从虚拟内存看都能申请0~4G的内存(假如是32位机),会有什么问题呢?为什么为内核分配内存的时候硬要规定3G以上的才是内核用的呢?

    作者回复: 这是由于x86的设计

    2021-08-09
    4
收起评论
显示
设置
留言
12
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部