UEFI学习笔记(八):Memory Services
- 一、内存服务概况
- 1、PEI阶段
- 2、DXE阶段(系统内存)
- 3、SMM阶段
- 二、HOB概述
- 1、为什么在PEI阶段要引入HOB?
- 2、HOB的类型
- 三、MEMORY类型
- 四、内存分布
- 1、PEI内存分布
- 2、DXE内存分布
- 参考文章
一、内存服务概况
本文主要针对系统内存。在SEC阶段,只有栈上的空间可用,没有可用的内存服务。内存服务在PEI(Pre-EFI Initialization)阶段才开始提供。
1、PEI阶段
分为物理内存初始化之前、物理内存初始化之后,在内存准备好之前,memory空间是非常少的。
CreateHob:CreateHob 是 UEFI 中用于创建 HOB(Hand-Off Block)的函数。HOB 是一种用于在引导过程中传递信息的结构体,主要在 PEI(Pre-EFI Initialization)阶段使用。
AllocatePool:轻量级的,不支持内存类型(都是Boot Service Data类型),没有FreePool API,不能释放。
AllocatePages/FreePages:不支持内存分配类型(都是Boot Service Data类型)
2、DXE阶段(系统内存)
物理内存都是存在,可以使用的。DXE阶段管理的是整个系统的memory,管理的空间较大。
AllocatePool/FreePool(UEFI的Boot Services Table提供):用于分配指定大小的内存块。所有的pool都有额外的信息标识起始地址,有一定的损耗
AllocatePages/FreePages(UEFI的Boot Services Table提供):用于释放之前通过 AllocatePool 分配的内存。用链表结构管理。
3、SMM阶段
在 SMM(系统管理模式)阶段,仅支持运行时数据和代码。SMM 在 SMRAM(系统管理 RAM)中有自己的专用内存空间,其他区域是不可访问的。
AllocatePool/FreePool:只支持runtime数据和代码
AllocatePages/FreePages:只支持runtime数据和代码
二、HOB概述
1、为什么在PEI阶段要引入HOB?
HOB(Hand-Off Block)主要用于在不同的阶段共享数据。由于Flash是只读的,直接修改全局变量是无效的。因此,在PEI(Pre-EFI Initialization)阶段,需要使用HOB来共享全局信息。HOB提供了一块临时内存,这块内存是CPU缓存的一部分,可以进行读写操作,从而在不同的阶段之间传递和共享信息。
2、HOB的类型
1) EFI_HOB_TYPE_HANDOFF:主要用于保存和传递在PEI阶段生成的信息,这些信息会被DXE阶段的驱动程序或其他组件使用。
2) EFI_HOB_TYPE_MEMORY_ALLOCATION:用于描述内存分配的信息。它通常用于传递有关分配的内存区域的元数据,包括内存的起始地址、大小和类型。
3) EFI_HOB_TYPE_RESOURCE_DESCRIPTION:用于描述系统资源的详细信息。这种类型的HOB包含有关系统资源的布局和分配信息,如内存区域、I/O端口、以及其他硬件资源的描述。
4) EFI_HOB_TYPE_GUID_EXTENTION:用于共享pre-memory和after-memory之间的数据。
5) EFI_HOB_TYPE_FV:用于描述固件卷(Firmware Volume)的信息。(是给DXE阶段用的)
6) EFI_HOB_TYPE_CPU:用于描述CPU的信息。
7) EFI_HOB_TYPE_MEMORY_POOL:提供有关内存池的配置和管理信息,帮助系统在不同的初始化阶段正确识别和利用内存池资源。
三、MEMORY类型
1、EfiLoaderCode/EfiLoaderData:用于的UEFI 应用程序代码/数据的内存区域
2、EfiBootServicesCode/EfiBootServicesData: UEFI/PEI/DXE 驱动
3、EfiRuntimeServicesCode/EfiRuntimeServicesData: Runtime驱动(不能被OS使用)
4、EfiReservedMemoryType: BIOS预留下来的一段内存,通常用于固件或其他系统组件在启动过程中的内部用途。(不能被OS使用)
5、EfiACPIReclaimMemory:用于标记ACPI需要的内存区域
6、EfiACPIMemoryNVS:用于标记 ACPI非易失性存储 (Non-Volatile Storage) 区域的内存。这种类型的内存用于存储需要在系统休眠和恢复过程中保持不变的数据。(不能被OS使用)
四、内存分布
1、PEI内存分布
1)在系统中,HOB(Hand-Off Block)内存分配是从低地址向高地址进行的。
2)HOB 和 AllocatePool 都位于低地址区域。
3)而 AllocatedPage 是从高地址向低地址分配的,位于高地址区域。
4)HOB的长度都是8字节对齐的
5)Top要大于Bottom
2、DXE内存分布
1)内存分配的方向从高往低
2)EFI_MEMORY_TYPE_INFORMATION 机制确保相同类型的内存尽可能集中分配。初次分配时需估算预留空间,并在启动前收集实际使用的内存信息保存为 EFI 变量。之后的启动可以使用更准确的预留值,若不够再从Remaining内存中分配。
3)ACPI、Reserved、Runtime Memory:是OS不可以回收的
4)将BIOS阶段预留的内存分配尽可能放置在高地址区域,以便操作系统能够使用连续的内存空间。
5)Pool 和 Page 在相同的内存空间中。申请 Pool 时,首先分配 Page,然后从 Page 中提供给 Pool 使用。Pool 和 Page 的管理都通过链表实现。
参考文章
【BIOS/UEFI】内存布局,包括 PEI Memory 和 DXE Memory