- 源码EDK2:Tianocore
- UEFI源码分析系列第二篇,DXE阶段的内存服务
- 第三部分,HeapGuard
- DXE阶段源码目录MdeModulePkg/Core/Dxe
- 基于开篇日(2018/04/18:16:30)时最新的EDk2版本,commit为
255101471918ed8840f2be347916b90eef0e9c08
从初始化过程入手
直到CoreAddMemoryDescriptor
才找到相关的内容
/** /Dxe/Mem/Page.c **/
536 VOID
537 CoreAddMemoryDescriptor (
538 IN EFI_MEMORY_TYPE Type,
539 IN EFI_PHYSICAL_ADDRESS Start,
540 IN UINT64 NumberOfPages,
541 IN UINT64 Attribute
542 )
543 {
544 EFI_PHYSICAL_ADDRESS End;
545 EFI_STATUS Status;
546 UINTN Index;
547 UINTN FreeIndex;
548
549 if ((Start & EFI_PAGE_MASK) != 0) {
550 return;
551 }
552
553 if (Type >= EfiMaxMemoryType && Type < MEMORY_TYPE_OEM_RESERVED_MIN) {
554 return;
555 }
556 CoreAcquireMemoryLock ();
557 End = Start + LShiftU64 (NumberOfPages, EFI_PAGE_SHIFT) - 1;
558 CoreAddRange (Type, Start, End, Attribute);
559 CoreFreeMemoryMapStack ();
560 CoreReleaseMemoryLock ();
561
562 ApplyMemoryProtectionPolicy (EfiMaxMemoryType, Type, Start,
563 LShiftU64 (NumberOfPages, EFI_PAGE_SHIFT));
在函数ApplyMemoryProtectionPolicy
中多了如下一段代码,主要包含两个函数IsHeapGuardEnabled
和IsGuardPage
。
1229 EFI_STATUS
1230 EFIAPI
1231 ApplyMemoryProtectionPolicy (
1232 IN EFI_MEMORY_TYPE OldType,
1233 IN EFI_MEMORY_TYPE NewType,
1234 IN EFI_PHYSICAL_ADDRESS Memory,
1235 IN UINT64 Length
1236 )
1237 {
1269 if (IsHeapGuardEnabled ()) {
1270 if (IsGuardPage (Memory)) {
1271 Memory += EFI_PAGE_SIZE;
1272 Length -= EFI_PAGE_SIZE;
1273 if (Length == 0) {
1274 return EFI_SUCCESS;
1275 }
1276 }
1277
1278 if (IsGuardPage (Memory + Length - EFI_PAGE_SIZE)) {
1279 Length -= EFI_PAGE_SIZE;
1280 if (Length == 0) {
1281 return EFI_SUCCESS;
1282 }
1283 }
1284 }
305 return gCpu->SetMemoryAttributes (gCpu, Memory, Length, NewAttributes);
306 }
函数IsHeapGuardEnable
显示是用来判断HeapGuard
是否Enabled
/** /Dxe/Mem/HeapGuard.c **/
753 BOOLEAN
754 IsHeapGuardEnabled (
755 VOID
756 )
757 {
758 return IsMemoryTypeToGuard (EfiMaxMemoryType, AllocateAnyPages,
759 GUARD_HEAP_TYPE_POOL|GUARD_HEAP_TYPE_PAGE);
760 }
函数IsMemoryTypeToGuard
则是进一步判断对应的内存类型是否Enabled
661 BOOLEAN
662 IsMemoryTypeToGuard (
663 IN EFI_MEMORY_TYPE MemoryType,
664 IN EFI_ALLOCATE_TYPE AllocateType,
665 IN UINT8 PageOrPool
666 )
667 {
主要是根据PCD
(全局配置数据库)的设置来判断是否Enabled。PCD的相关内容可以参考文献。
如根据PcdHeapGuardPropertyMask
判断是否开启了page
和pool
的Guard。
685 if ((PcdGet8 (PcdHeapGuardPropertyMask) & PageOrPool) == 0) {
686 return