当前位置: 首页 > news >正文

【UEFI系列】EFI Memory Map内存映射 and type

前言

memory map主要分为两个部分,一个是系统能用的memory,通常allocate的部分,能当作堆栈存放数据存放代码、系统能用的memory。另一部分就是IO空间,一些设备比如PCI设备用的部分(MMio),它们所处的其实是分散的地方,通过映射、映射到连续的一段内存空间。

内存硬件层面:
channel > DIMM > rank > chip > bank > row/column
一个channel槽一般设计为1~4个DIMM口,可供插入DIMM条,DIMM就是我们通常说的内存条。
一个DIMM分为2面,一面为一个Rank,一个Rank有多个chip颗粒(DDR),一个chip颗粒上有多层Bank,每层Bank又有横列column数列row。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这里图上标SPD的实际上是EEPROM芯片,SPD是EEPROM存储的数据里面一项重要数据。

Memory Init

1.CAR: Cache as Ram,UEFI SEC最开始的CPU缓存当内存堆栈用
2.Init Memory Controler,内存插上去之后需要一些初始化和training才能使用。设备需要满足一些时序才能和CPU通信,内存需要满足一些比较复杂的时序。
3.read SPD with SMBUS, record delay of memory,用SMBUS去读内存的SPD,记录一些信息比如延时。但这个信息是需要修正的。
4.memory training, get Timing and Voltage of DIMM。Intel的话,training是在bios上运行的(intel提供的MRC code,发送一些信号,得到反馈,一直重复来调整延时和电压,得到一个比较准确的信息,然后记录下来)。AMD的话,自己有芯片去运行。
5.record memory info of HOB,PEI阶段存到HOB里去,DXE可以获取到。

Memory Management

地址空间在上电的时候回去检测是不是重启的。
如果是重启,有些设置是通过variable保存下来的,这些设置会被放到hob里。不是重启的话(可能是第一次刷板子开机)回去读默认值,再重启一次(这也就是为什么有些平台的CPU风扇开了又关然后又开)。
在这里插入图片描述

Hardware Perspective

Memory Map内存分布图(32位)

从上到下(地址从高到低)依次为
MMIo:Memory map IO
TOLUD:Top of Low Usable DRAM(系统可访问物理内存的最高地址边界)
System Memory

PCI memory range涉及到PCI配置表,以0XF开头,具体可以看我另外一篇讲的PCI&PCIe的。
在这里插入图片描述
如果是32bit以上(64bit),4G以上的寻址空间,就有更多的内存可以使用。
4G以上一部分也被拿来当作OS可用内存,再reclaim一段TOLUD到0xFFFFFFFF的内存大小(实际上只是获取了大小,数据并不是mmio的内容),再继续4G以上部分的mmio。

  1. Reclaim 的不是 MMIO 区域,而是被 MMIO“挤掉”的 DRAM
    你有比如 8GB 的物理内存,但 CPU 的地址空间从 0x00000000 到 0xFFFFFFFF(4GB)之间被 MMIO 占了一部分。
    那么原本应该映射在这段地址上的 DRAM 就没法映射进来。
    这部分 DRAM 并没有消失,而是被“挪”到 4GB 以上的地址空间继续使用。
  2. Reclaim 区域的大小 ≈ MMIO 占用的大小
    是的,被 MMIO 占用多少地址空间,就会有多少 DRAM 被挤出去,然后 reclaim 回来。
    所以 reclaim 区域的大小 ≈ 0xFFFFFFFF - TOLUD + 1
  3. Reclaim 出来的那段 DRAM 是可以正常使用的
    操作系统通过 BIOS 提供的 e820 表知道哪些地址是可用内存。
    那段 reclaim 出来的 DRAM 会被标记为“可用”,可以被 OS 分配给用户进程、内核、缓存等。

如下:
在这里插入图片描述

PEI(Hob)

初始化内存,有的Hob要存放内存相关信息,DXE时候去获取。
可以看到绿色部分是HOB部分的(包含一个PHIT HOB头,里面放了物理起始地址和Hob list可用内存范围),hob list的大小是由代码固定好的,HOB一旦创建便不可删除或修改位置,仅支持追加(在最后面)操作。
蓝色部分是初始化好但还没用的,黄色是已经被分配过的地方。
最开始PeiMemoryTop和PeiFreeMemoryTop是一样的,每分配一段内存PeiFreeMemoryTop就会向下,EfiFreeMemoryBottom就会往上来用hob记录内存使用(黄色区域增多,绿色部分增多,蓝色区域减少)。

在这里插入图片描述

DXE(Gcd)

初始化驱动阶段。
这里4G以上就是之前讲的64位平台所拥有的内存扩展可用区域。
mmio同之前讲的一样,在4G最高地址。

DXE最开始的时候,会内存服务,GCD:Global Coherency Domain。
去分配一些比较大的空间。
GCD阶段,内存分为四个type:
1.Nonexistent memory:没用过的内存
2.System memory:系统内存
3.Memory mapped I/O:mmio
4.Reserved memory:预留内存(申请了准备用但还没有用的)

红框里的都是OS需要用到的,但是它实际上并不是连续的一块,是动态分配的,通过GCD的这些函数。
在这里插入图片描述
函数如图。
以下是函数具体执行。
原本都是Nonexistent memory,之后add成不同的类型:MMIO/Reserved/System memory。
在这里插入图片描述
GetMemoryMap

跑完UEFI Boot,从OS来看内存分布(BS是boot service):
可以通过GetMemoryMap来得到这张表,会在ExitBootService之前调用这个函数,会把这些信息传给OS。
因为OS需要知道物理内存是怎么用的,有些内存是不能被bios使用的也会被标注出来。OS需要知道那些内存是它可用的、哪些不可用。
在这里插入图片描述
这是函数的参数:
在这里插入图片描述
其中MemoryMap的PhysicalStart一段内存空间的地址。
这是每个EFI_MEMORY_DESCRIPTOR的结构:

typedef struct {UINT32                Type;           // 内存类型(如代码、数据、保留等)EFI_PHYSICAL_ADDRESS  PhysicalStart;  // 物理起始地址,理解为寻址空间(32位对应4G寻址空间那种)EFI_VIRTUAL_ADDRESS   VirtualStart;   // 虚拟起始地址(未映射时为0)UINT64                NumberOfPages;  // 页数(每页=4KB),可以看做内存区段大小的一种计量单位UINT64                Attribute;      // 属性(可执行、缓存策略等)
} EFI_MEMORY_DESCRIPTOR;

也可以通过memmap指令在shell(还没有执行ExitBootService,可以回到Setup页面)下获得:
(1Page=4K)
在这里插入图片描述

http://www.dtcms.com/a/307086.html

相关文章:

  • cpp-httplib 线程安全
  • Tableau 2019可视化数据分析软件安装包下载安装教程
  • Java基础面试总结(八股)
  • 【硬件-笔试面试题】硬件/电子工程师,笔试面试题-49,(知识点:OSI模型,物理层、数据链路层、网络层)
  • 复现CLIP(对比语言图像预训练)
  • windows通过WSL配置linux环境
  • 重生之我在10天内卷赢C++ - DAY 2
  • UNet改进(27):对抗注意力机制如何提升UNet的图像分割性能
  • Effective C++ 条款11:在operator=中处理“自我赋值”
  • 【通识】计算机网络
  • 游戏盾能够防御哪些类型攻击?从哪些方面防护?
  • 智能体产品化的关键突破:企业智能化转型的“最后一公里”如何迈过?
  • 【从0开始学习Java | 第8篇】抽象类和接口
  • 力扣热题100---------35.搜索插入为位置
  • NLU 语义解析评测实践:基于函数调用的 ACC、ROUGE 与 BLEU 综合指标
  • LangGraph底层API学习
  • 论文阅读|CVPR 2025|Mamba进一步研究|GroupMamba
  • RNN、LSTM、Transformer推荐博文
  • AI在软件测试中的应用:自动化测试框架、智能缺陷检测与A/B测试优化
  • 人工智能如何改变项目管理:应用、影响与趋势
  • 无监督MVSNet系列网络概述
  • 并查集算法:Python实现与工程实践指南
  • 如何协调跨部门资源?核心要点分析
  • Java String类练习
  • 客户满意度调查:助力商场提升运营效能​(客户满意度调查)
  • 8.Linux : 日志的管理与时钟同步的配置
  • 代码随想录算法训练营第五十六天|动态规划part6
  • 手动 对列表字段进行排序
  • 【高等数学】第七章 微分方程——第四节 一阶线性微分方程
  • LNN+XGBoost:优化多层供应链订购:缓解牛鞭效应