当前位置:首页 > 学习资源 > 讲师博文 > 嵌入式基础知识--存储管理之分页管理

嵌入式基础知识--存储管理之分页管理 时间:2023-10-19      来源:华清远见

现代计算机之父冯诺伊曼最先提出程序存储的思想,并成功将其运用在计算机的设计之中,该思想约定了用二进制进行计算和存储,还定义计算机基本结构为 5 个部分,分别是中央处理器(CPU)、内存、输入设备、输出设备、总线。

存储器:代码跟数据在RAM跟ROM中是线性存储, 数据存储的单位是一个二进制位。最小的存储单位是字节。

总线:总线是用于 CPU 和内存以及其他设备之间的通信,总线主要有三种:

地址总线:用于指定 CPU 将要操作的内存地址。

数据总线:用于读写内存的数据。

控制总线:用于发送和接收信号,比如中断、设备复位等信号,CPU 收到信 号后响应,这时也需要控制总线。

输入/输出设备:输入设备向计算机输入数据,计算机经过计算后,把数据输出给输出设备。比如键盘按键时需要和 CPU 进行交互,这时就需要用到控制总线。

 

CPU:中央处理器,类比人脑,作为计算机系统的运算和控制核心,是信息处理、程序运行的最终执行单元。CPU用寄存器存储计算时所需数据,寄存器一般有三种:

通用寄存器:用来存放需要进行运算的数据,比如需进行加法运算的两个数据。

程序计数器:用来存储 CPU 要执行下一条指令所在的内存地址。

指令寄存器:用来存放程序计数器指向的指令本身。

 

在冯诺伊曼体系下电脑指令执行的过程:

CPU读取程序计数器获得指令内存地址,CPU控制单元操作地址总线从内存地址拿到数据,数据通过数据总线到达CPU被存入指令寄存器。

CPU分析指令寄存器中的指令,如果是计算类型的指令交给逻辑运算单元,如果是存储类型的指令交给控制单元执行。

CPU 执行完指令后程序计数器的值通过自增指向下个指令,比如32位CPU会自增4,循环往复。

有了冯诺伊曼计算机体系后,电脑想要为用户提供便捷的服务还需要安装个操作系统Operation System,操作系统是覆盖在硬件上的一层特殊软件,它管理计算机的硬件和软件资源,为其他应用程序提供大量服务。可以理解为操作系统是日常应用程序跟硬件之间的接口。日常你经常在用Windows/Linux 系统,操作系统给我们提供了超级大的便利,但是你了解操作系统么?操作系统是如何进行内存管理、进程管理文件管理、网络管理、设备管理的呢?接下来我们主要研究一下关于内存管理的相关知识中的内存分页管理。

我们的电脑是32位操作系统,那可支持的最大内存就是4G,你有没有好奇为什么可以同时运行2个以上的2G内存的程序。应用程序不是直接使用的物理地址,操作系统为每个运行的进程分配了一套虚拟地址,每个进程都有自己的虚拟内存地址,进程是无法直接进行物理内存地址的访问的。至于虚拟地址跟物理地址的映射,进程是感知不到的!操作系统自身会提供一套机制将不同进程的虚拟地址和不同内存的物理地址进行映射。

MMU:

Memory Management Unit 内存管理单元是一种负责处理CPU内存访问请求的计算机硬件。它的功能包括虚拟地址到物理地址的转换、内存保护、中央处理器高速缓存的控制。现代 CPU 基本上都选择了使用 MMU。当进程持有虚拟内存地址的时候,CPU执行该进程时会操作虚拟内存,而MMU会自动的将虚拟内存的操作映射到物理内存上。

内存页管理方式

内存分页,整个虚拟内存和物理内存切成固定尺寸大小段。每个固定大小的段尺寸称之为页Page,在 Linux 系统中Page = 4KB。然后虚拟内存跟物理内存之间通过页表来实现映射。采用内存分页时内存的释放跟使用都是以页为单位的,也就不会产生内存碎片了。当空间不够时根据操作系统调度算法,可将最少用的内存页面 swap-out换出到磁盘,用时候再swap-in换入,尽可能的减少磁盘刷写量,提高内存交互效率。分页模式下虚拟地址主要由页号跟页内偏移量两部分组成。通过页号查询页表找到物理内存地址,然后再配合页内偏移量就找到了真正的物理内存地址。

使用 4K 字节固定大小的页面,每个页面均是 4KB,并且对其于 4K 地址边界处。 这表示分页机制把 2^32字节(4GB)的线性地址空间划分成 2^20(1M = 1048576)个页面。分页机制通过把线性地址空间中的页面重新定位到物理地址空间中进行操作。由于 4K 大小的页面作为一个单元进行映射,并且对其于 4K 边界,因此线性地址的低 12 位可做为页内偏移地量直接作为物理地址的低 12 位。分页机制执行的重定向功能可以看作是把线性地址的高 20 位转换到对应物理地址的高 20 位。

32位操作系统环境下进程可操作的虚拟地址是4GB,假设一个虚拟页大小为4KB,那需要4GB/4KB = 2^20 个页信息。一行页表记录为4字节,2^20等价于4MB页表存储信息。这只是一个进程需要的,如果10个、100个、1000个呢?仅仅是页表存储都占据超大内存了。为了解决这个问题就需要用到 多级页表,核心思想就是局部性分配。在32位的操作系统中将将4G空间分为 1024 行页目录项目(4KB),每个页目录项又对应1024行页表项。

32位系统二级分页

控制寄存器cr3中存放了页目录的物理地址,通过cr3寄存器可以找到页目录,而32位线性地址中的Directory部分决定页目录中的目录项,而页目录项中存放了要找的页表的物理基地址,再结合线性地址中的中间10位页表项,就可以找到页框的页表项。线性地址中的Offset部分占12位,因此页框的物理地址 + 线性地址Offset部分 = 页框中的任何一个字节。

分页后一级页就等价于4G虚拟地址空间,并且如果一级页表中那些地址没有就不需要再创建二级页表了!核心思想就是按需创建,当系统给每个进程分配4G空间,进程不可能占据全部内存的,如果一级目录页只有10%用到了,此时页表空间 = 一级页表4KB + 0.1 * 4MB 。这比单独的每个进程占据4M好用多了!

多层分页的弊端就是访问时间的增加

使用页表时读取内存中一页内容需要2次访问内存,访问页表项 + 并读取的一页数据。

使用二级页表的话需要三次访问,访问页目录项 + 访问页表项 + 访问并读取的一页数据。访存次数的增加也就意味着访问数据所花费的总时间增加。

而对于64位系统,二级分页就无法满足了,Linux 从2.6.11开始采用四级分页模型。

Page Global Directory 全局页目录项

Page Upper Directory 上层页目录项

Page Middle Directory 中间页目录项

Page Table Entry 页表项

Offset 偏移量。

TLB

Translation Lookaside Buffer 可翻译为地址转换后援缓冲器,简称为快表,属于CPU内部的一个模块,TLB是MMU的一部分,实质是cache,它所缓存的是最近使用的数据的页表项(虚拟地址到物理地址的映射)。他的出现是为了加快访问数据(内存)的速度,减少重复的页表查找。当然它不是必须要有的,但有它,速度就更快。

TLB很小,因此缓存的东西也不多。主要缓存最近使用的数据的数据映射。TLB结构如下图:

TLB查询

如果一个需要访问内存中的一个数据,给定这个数据的虚拟地址,查询TLB,发现有hit,直接得到物理地址,在内存根据物理地址取数据。如果TLB没有这个虚拟地址miss,那么只能费力地通过页表来查找了。日常CPU读取一个数据的流程如下:

读取数据流程图

当进程地址空间进行了上下文切换时,比如现在是进程1运行,TLB中放的是进程1的相关数据的地址,突然切换到进程2,TLB中原有的数据不是进程2相关的,此时TLB刷新数据有两种办法。

全部刷新:很简单,但花销大,很多不必刷新的数据也进行刷新,增加了无畏的花销。

部分刷新:根据标志位,刷新需要刷新的数据,保留不需要刷新的数据。

以上就是关于内存分页管理的简单的分析,当然,内存管理还有分段管理,段页式管理等等,我们以后再分析。

 

上一篇:设备树

下一篇:嵌入式软件工具分享

戳我查看2020年嵌入式每月就业风云榜

点我了解华清远见高校学霸学习秘籍

猜你关心企业是如何评价华清学员的

干货分享
相关新闻
前台专线:010-82525158 企业培训洽谈专线:010-82525379 院校合作洽谈专线:010-82525379 Copyright © 2004-2024 北京华清远见科技发展有限公司 版权所有 ,京ICP备16055225号-5京公海网安备11010802025203号

回到顶部