您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

内存是怎么映射到物理地址空间的?内存是连续分布的吗?

时间:2019-08-26 12:14:12  来源:  作者:
内存是怎么映射到物理地址空间的?内存是连续分布的吗?

 

如果我们将两个4G内存插入内存插槽,得到的内存地址空间是0到8G吗?是不是0到4G是第一根内存,4到8G是第二根内存呢?实际情况相差甚远,内存在物理地址空间的映射是分散的。一部分原因是4G以下有Memory map IO(mmio)空间和PCIe的配置空间,另一个原因是Interleaving会打撒内存地址到各个Channel、DIMM甚至是Rank和bank上。今天我们就一起来了解一下x86系统的地址空间分布。

物理地址空间

一个典型的物理地址空间是这样的:

内存是怎么映射到物理地址空间的?内存是连续分布的吗?

 

其中只有灰色部分是真正的内存,其余都是MMIO。而内存被分为High DRAM和Low DRAM,如图:

内存是怎么映射到物理地址空间的?内存是连续分布的吗?

 

为什么要把内存强行分割成两块呢?因为历史的包袱。最早内存都很小,32位的地址(4G)空间看起来永远也用不完,低地址被分配给内存用,高地址就自然而然被分配用来给Memory map IO。既然已经分给它们了,为了兼容以前的驱动,这一块就被固定下来。再有内存就只能从4G以上分配了。

Low MMIO和High MMIO

Low MMIO结构如下图:

内存是怎么映射到物理地址空间的?内存是连续分布的吗?

 

其中有几块要特别说明一下:

1.Boot Vector的空间是BIOS内容映射的地址,它的大小是可以调节的,为了满足不同大小的BIOS。

2.Local APIC是APIC中断模式各个内核local APIC寄存器的映射地址。

3.PCI ECAM也有叫做PCIBAR,是PCIe配置地址空间的映射地址。它的起始地址可调,台式机BIOS一般会把它设置得很高,这样4G以下内存会比较大,方便32位windows使用。举个例子,如果我们把PCIe BAR(BEGREG)设为0x80000000,那么尽管插了8G DIMM,4G以下也不会超过2G的内存可以使用,而2到8G的真实内存都被映射到在4G地址空间以上了,而这些是32位Windows使用不了的。所以有的主板运行32位操作系统发现可用内存小了一大块就是这个原因。它的大小可以修改,一般可以设为64MB和128MB。

High MMIO被BIOS保留作为64位mmio分配之用,例如PCIe的64位BAR等。

Low DRAM和High DRAM

4G以下内存最高地址叫做BMBOUND,也有叫做Top of Low Usable DRAM (TOLUD) 。BIOS也并不是把这些都报告给操作系统,而是要在里面划分出一部分给核显、ME和SMM等功能:

内存是怎么映射到物理地址空间的?内存是连续分布的吗?

 

红框中是在low DRAM被“偷”的部分

4G以上的内存最高端叫做Top of Up Usable DRAM (TOUUD) ,再上面就是High MMIO了。

1MB以下比较特殊,里面全部都是已经被淘汰的传统BIOS和DOS关心的内容,我们叫它DOS Space或者Legacy Region:

内存是怎么映射到物理地址空间的?内存是连续分布的吗?

 

在那里,我们习惯用传统的实模式地址来划分它们的具体内容:

1.0~640KB,传统DOS空间。

2.A段和B段,传统SMM空间。VGA的MMIO也被映射到这里,可以通过寄存器切换。

3.C段和D段,legacy opROM映射空间和EBDA空间。

4.E段和F段,BIOS空间的Lower和Upper映射地址。BIOS的rom内容也会被映射到这里,方便Legacy BIOS实模式跳转到保护模式。

内存的Interleave

从前面可以看出内存在地址空间上被拆分成两块:Low DRAM和High DRAM。那么在每块地址空间上分配连续吗?现代内存系统在引入多通道后,为了规避数据的局部性(这也是Cache为什么起作用的原因)对多通道性能的影响,BIOS基本缺省全部开启了Interleaving,过去美好的DIMM 0和DIMM 1挨个连续分配的日子一去不复返了。

什么是Interleaving?简单来说,就是让内存交错起来,如下面的动图:

 

内存是怎么映射到物理地址空间的?内存是连续分布的吗?

来自wikipedia, 参考资料1

这是一个bank层级的模4的interleaving。在桌面电脑上,常见的还有Channel级的、DIMM级的和Rank级的。

服务器上Interleaving更是不可或缺,它的粒度更细,可以达到数十bytes层级的interleave,它和内存的其他特性,如类似磁盘阵列RAID的内存spare, mirror特性,构成了复杂异常的内存映射系统。在BIOS里面,台式机/笔记本内存映射相对简单,只有一个大表和数十个寄存器;而在服务器BIOS中,有数个相互关联的大表和寄存器阵列来解码(decode)内存的请求,代码的硬件逻辑也是相当复杂。关于它,我会有一篇专栏文章讨论地址译码和地址反向解码,详细内容那里再说,这里只需要知道,物理内存分布在各个DIMM上就够了。

物理地址到内存单元的反推

BIOS实际上一手导演的内存的分配,它当然可以从任何物理地址反推回内存的单元地址。我们可以用下面一组数据来唯一确定某个内存单元:

Channel #;DIMM #; Rank #;Bank #;Row #;Column #

在内存分配表缺失的情况下,BIOS甚至可以通过它填过的寄存器重建这个映射表。但实际上BIOS并不希望一般用户知道这些信息,因为有安全性问题。

暴露内存信息容易招来内存侧信道攻击(Side Channel),比较有名的有Row hammer攻击。简单的来说它是通过反复写某个内存单元,借助内存的特性,希望影响相邻Row/Column的内容。详细内容可以参考这里:

内存不刷新会怎样?有趣的内存物理攻击和旁路攻击

有些情况确实需要知道这些信息,就是内存出错的时候。和大家想象的不同,内存是会出错的。尤其云服务器中内存的出错是十分频繁的。出错起来也千奇百怪,开始可能是偶尔的随机错误,经过ECC等校正后,就再也不会复现;而有时是某个Bit总是出错,进而慢慢的整个row、column或者相邻的cell开始出错,从可以纠正的错误变成不可修正的错误,导致服务器必须停机。这时候就必须知道哪个内存坏了,进而换掉它。BIOS的报错是通过WHEA:

报告给操作系统,但这个信息里面只有物理地址,如何才能知道是哪个内存单元坏了呢?在linux上面可以通过edca(参考资料4),有编程经验的同学可以通过edca的程序接口(参考资料3),可以得到更加丰富的信息。

如何关掉Interleaving

对内存有特殊需求的朋友,如果希望内存连续,可以在BIOS里面关闭所有的Interleaving来达成这个目标:

内存是怎么映射到物理地址空间的?内存是连续分布的吗?

 

注意是所有的。之后可以通过SMBIOS来看到内存分布信息(dmidecode)。

结论

BIOS作为内存的大管家,也负责内存的分配和映射memory map。它会把这些信息通过E820, GetMemoryMap函数和SMBIOS传递给操作系统。操作系统在此基础上再建立页表,产生虚拟地址。



Tags:内存映射   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
如果我们将两个4G内存插入内存插槽,得到的内存地址空间是0到8G吗?是不是0到4G是第一根内存,4到8G是第二根内存呢?实际情况相差甚远,内存在物理地址空间的映射是分散的。一部分原...【详细内容】
2019-08-26  Tags: 内存映射  点击:(272)  评论:(0)  加入收藏
内存映射文件(Memory-mapped File),指的是将一段虚拟内存逐字节映射于一个文件,使得应用程序处理文件如同访问主内存(但在真正使用到这些数据前却不会消耗物理内存,也不会有读写...【详细内容】
2019-08-14  Tags: 内存映射  点击:(207)  评论:(0)  加入收藏
▌简易百科推荐
本文分为三个等级自顶向下地分析了glibc中内存分配与回收的过程。本文不过度关注细节,因此只是分别从arena层次、bin层次、chunk层次进行图解,而不涉及有关指针的具体操作。前...【详细内容】
2021-12-28  linux技术栈    Tags:glibc   点击:(3)  评论:(0)  加入收藏
摘 要 (OF作品展示)OF之前介绍了用python实现数据可视化、数据分析及一些小项目,但基本都是后端的知识。想要做一个好看的可视化大屏,我们还要学一些前端的知识(vue),网上有很多比...【详细内容】
2021-12-27  项目与数据管理    Tags:Vue   点击:(2)  评论:(0)  加入收藏
程序是如何被执行的  程序是如何被执行的?许多开发者可能也没法回答这个问题,大多数人更注重的是如何编写程序,却不会太注意编写好的程序是如何被运行,这并不是一个好...【详细内容】
2021-12-23  IT学习日记    Tags:程序   点击:(9)  评论:(0)  加入收藏
阅读收获✔️1. 了解单点登录实现原理✔️2. 掌握快速使用xxl-sso接入单点登录功能一、早期的多系统登录解决方案 单系统登录解决方案的核心是cookie,cookie携带会话id在浏览器...【详细内容】
2021-12-23  程序yuan    Tags:单点登录(   点击:(8)  评论:(0)  加入收藏
下载Eclipse RCP IDE如果你电脑上还没有安装Eclipse,那么请到这里下载对应版本的软件进行安装。具体的安装步骤就不在这赘述了。创建第一个标准Eclipse RCP应用(总共分为六步)1...【详细内容】
2021-12-22  阿福ChrisYuan    Tags:RCP应用   点击:(7)  评论:(0)  加入收藏
今天想简单聊一聊 Token 的 Value Capture,就是币的价值问题。首先说明啊,这个话题包含的内容非常之光,Token 的经济学设计也可以包含诸多问题,所以几乎不可能把这个问题说的清...【详细内容】
2021-12-21  唐少华TSH    Tags:Token   点击:(10)  评论:(0)  加入收藏
实现效果:假如有10条数据,分组展示,默认在当前页面展示4个,点击换一批,从第5个开始继续展示,到最后一组,再重新返回到第一组 data() { return { qList: [], //处理后...【详细内容】
2021-12-17  Mason程    Tags:VUE   点击:(14)  评论:(0)  加入收藏
什么是性能调优?(what) 为什么需要性能调优?(why) 什么时候需要性能调优?(when) 什么地方需要性能调优?(where) 什么时候来进行性能调优?(who) 怎么样进行性能调优?(How) 硬件配...【详细内容】
2021-12-16  软件测试小p    Tags:性能调优   点击:(20)  评论:(0)  加入收藏
Tasker 是一款适用于 Android 设备的高级自动化应用,它可以通过脚本让重复性的操作自动运行,提高效率。 不知道从哪里听说的抖音 app 会导致 OLED 屏幕烧屏。于是就现学现卖,自...【详细内容】
2021-12-15  ITBang    Tags:抖音防烧屏   点击:(25)  评论:(0)  加入收藏
11 月 23 日,Rust Moderation Team(审核团队)在 GitHub 上发布了辞职公告,即刻生效。根据公告,审核团队集体辞职是为了抗议 Rust 核心团队(Core team)在执行社区行为准则和标准上...【详细内容】
2021-12-15  InfoQ    Tags:Rust   点击:(25)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条