Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
btwise
OpenCorePKG_MOD
提交
bed4ffe1
O
OpenCorePKG_MOD
项目概览
btwise
/
OpenCorePKG_MOD
通知
26
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
O
OpenCorePKG_MOD
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
bed4ffe1
编写于
7月 21, 2019
作者:
V
vit9696
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
OcMemoryLib: Add memory map functions
上级
36260288
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
425 addition
and
92 deletion
+425
-92
Include/Library/OcMemoryLib.h
Include/Library/OcMemoryLib.h
+75
-1
Library/OcMemoryLib/GetMemoryMap.c
Library/OcMemoryLib/GetMemoryMap.c
+0
-90
Library/OcMemoryLib/MemoryMap.c
Library/OcMemoryLib/MemoryMap.c
+349
-0
Library/OcMemoryLib/OcMemoryLib.inf
Library/OcMemoryLib/OcMemoryLib.inf
+1
-1
未找到文件。
Include/Library/OcMemoryLib.h
浏览文件 @
bed4ffe1
...
...
@@ -49,7 +49,7 @@ LegacyRegionUnlock (
@param[out] MemoryMapSize Resulting memory map size in bytes.
@param[out] DescriptorSize Resulting memory map descriptor size in bytes.
@param[out] MapKey Memory map key, optional.
@param[out] DescriptorVersion Memory map version, optional.
@param[out] DescriptorVersion Memory map
descriptor
version, optional.
@retval current memory map or NULL.
**/
...
...
@@ -61,4 +61,78 @@ GetCurrentMemoryMap (
OUT
UINT32
*
DescriptorVersion
OPTIONAL
);
/**
Get current memory map of custom allocation.
@param[out] MemoryMapSize Resulting memory map size in bytes.
@param[out] MemoryMap Resulting memory map.
@param[out] MapKey Memory map key.
@param[out] DescriptorSize Resulting memory map descriptor size in bytes.
@param[out] DescriptorVersion Memory map descriptor version.
@param[in] GetMemoryMap Custom GetMemoryMap implementation to use, optional.
@param[in,out] TopMemory Base top address for AllocatePagesFromTop allocation.
@retval EFI_SUCCESS on success.
**/
EFI_STATUS
GetCurrentMemoryMapAlloc
(
OUT
UINTN
*
MemoryMapSize
,
OUT
EFI_MEMORY_DESCRIPTOR
**
MemoryMap
,
OUT
UINTN
*
MapKey
,
OUT
UINTN
*
DescriptorSize
,
OUT
UINT32
*
DescriptorVersion
,
IN
EFI_GET_MEMORY_MAP
GetMemoryMap
OPTIONAL
,
IN
OUT
UINTN
*
TopMemory
OPTIONAL
);
/**
Shrinks memory map by joining non-runtime records.
@param[in,out] MemoryMapSize Memory map size in bytes, updated on shrink.
@param[in,out] MemoryMap Memory map to shrink.
@param[in] DescriptorSize Memory map descriptor size in bytes.
**/
VOID
ShrinkMemoryMap
(
IN
OUT
UINTN
*
MemoryMapSize
,
IN
OUT
EFI_MEMORY_DESCRIPTOR
*
MemoryMap
,
IN
UINTN
DescriptorSize
);
/**
Check range allocation compatibility callback.
@param[in] Address Starting address.
@param[in] Size Size of memory range.
@retval TRUE when suitable for allocation.
**/
typedef
BOOLEAN
(
*
CHECK_ALLOCATION_RANGE
)
(
IN
EFI_PHYSICAL_ADDRESS
Address
,
IN
UINTN
Size
);
/**
Alloctes pages from the top of physical memory up to address specified in Memory.
Unlike AllocateMaxAddress, this method guarantees to choose top most address.
@param[in] MemoryType Allocated memory type.
@param[in] Pages Amount of pages to allocate.
@param[in,out] Memory Top address for input, allocated address for output.
@param[in] GetMemoryMap Custom GetMemoryMap implementation to use, optional.
@param[in] CheckRange Handler allowing to not allocate select ranges, optional.
@retval EFI_SUCCESS on successful allocation.
**/
RETURN_STATUS
AllocatePagesFromTop
(
IN
EFI_MEMORY_TYPE
MemoryType
,
IN
UINTN
Pages
,
IN
OUT
EFI_PHYSICAL_ADDRESS
*
Memory
,
IN
EFI_GET_MEMORY_MAP
GetMemoryMap
OPTIONAL
,
IN
CHECK_ALLOCATION_RANGE
CheckRange
OPTIONAL
);
#endif // OC_MEMORY_LIB_H
Library/OcMemoryLib/GetMemoryMap.c
已删除
100644 → 0
浏览文件 @
36260288
/** @file
Copyright (C) 2019, vit9696. All rights reserved.
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <Uefi.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/OcGuardLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
EFI_MEMORY_DESCRIPTOR
*
GetCurrentMemoryMap
(
OUT
UINTN
*
MemoryMapSize
,
OUT
UINTN
*
DescriptorSize
,
OUT
UINTN
*
MapKey
OPTIONAL
,
OUT
UINT32
*
DescriptorVersion
OPTIONAL
)
{
EFI_MEMORY_DESCRIPTOR
*
MemoryMap
;
EFI_STATUS
Status
;
UINTN
MapKeyValue
;
UINT32
DescriptorVersionValue
;
BOOLEAN
Result
;
*
MemoryMapSize
=
0
;
Status
=
gBS
->
GetMemoryMap
(
MemoryMapSize
,
NULL
,
&
MapKeyValue
,
DescriptorSize
,
&
DescriptorVersionValue
);
if
(
Status
!=
EFI_BUFFER_TOO_SMALL
)
{
return
NULL
;
}
//
// Apple uses 1024 as constant, however it will grow by at least
// DescriptorSize.
//
Result
=
OcOverflowAddUN
(
*
MemoryMapSize
,
MAX
(
*
DescriptorSize
,
1024
),
MemoryMapSize
);
if
(
Result
)
{
return
NULL
;
}
MemoryMap
=
AllocatePool
(
*
MemoryMapSize
);
if
(
MemoryMap
==
NULL
)
{
return
NULL
;
}
Status
=
gBS
->
GetMemoryMap
(
MemoryMapSize
,
MemoryMap
,
&
MapKeyValue
,
DescriptorSize
,
&
DescriptorVersionValue
);
if
(
EFI_ERROR
(
Status
))
{
FreePool
(
MemoryMap
);
return
NULL
;
}
if
(
MapKey
!=
NULL
)
{
*
MapKey
=
MapKeyValue
;
}
if
(
DescriptorVersion
!=
NULL
)
{
*
DescriptorVersion
=
DescriptorVersionValue
;
}
return
MemoryMap
;
}
Library/OcMemoryLib/MemoryMap.c
0 → 100644
浏览文件 @
bed4ffe1
/** @file
Copyright (C) 2019, vit9696. All rights reserved.
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <Uefi.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/OcGuardLib.h>
#include <Library/OcMemoryLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
/**
* Reverse equivalent of NEXT_MEMORY_DESCRIPTOR.
*/
#define PREV_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \
((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size)))
EFI_MEMORY_DESCRIPTOR
*
GetCurrentMemoryMap
(
OUT
UINTN
*
MemoryMapSize
,
OUT
UINTN
*
DescriptorSize
,
OUT
UINTN
*
MapKey
OPTIONAL
,
OUT
UINT32
*
DescriptorVersion
OPTIONAL
)
{
EFI_MEMORY_DESCRIPTOR
*
MemoryMap
;
EFI_STATUS
Status
;
UINTN
MapKeyValue
;
UINT32
DescriptorVersionValue
;
BOOLEAN
Result
;
*
MemoryMapSize
=
0
;
Status
=
gBS
->
GetMemoryMap
(
MemoryMapSize
,
NULL
,
&
MapKeyValue
,
DescriptorSize
,
&
DescriptorVersionValue
);
if
(
Status
!=
EFI_BUFFER_TOO_SMALL
)
{
return
NULL
;
}
//
// Apple uses 1024 as constant, however it will grow by at least
// DescriptorSize.
//
Result
=
OcOverflowAddUN
(
*
MemoryMapSize
,
MAX
(
*
DescriptorSize
,
1024
),
MemoryMapSize
);
if
(
Result
)
{
return
NULL
;
}
MemoryMap
=
AllocatePool
(
*
MemoryMapSize
);
if
(
MemoryMap
==
NULL
)
{
return
NULL
;
}
Status
=
gBS
->
GetMemoryMap
(
MemoryMapSize
,
MemoryMap
,
&
MapKeyValue
,
DescriptorSize
,
&
DescriptorVersionValue
);
if
(
EFI_ERROR
(
Status
))
{
FreePool
(
MemoryMap
);
return
NULL
;
}
if
(
MapKey
!=
NULL
)
{
*
MapKey
=
MapKeyValue
;
}
if
(
DescriptorVersion
!=
NULL
)
{
*
DescriptorVersion
=
DescriptorVersionValue
;
}
return
MemoryMap
;
}
EFI_STATUS
GetCurrentMemoryMapAlloc
(
OUT
UINTN
*
MemoryMapSize
,
OUT
EFI_MEMORY_DESCRIPTOR
**
MemoryMap
,
OUT
UINTN
*
MapKey
,
OUT
UINTN
*
DescriptorSize
,
OUT
UINT32
*
DescriptorVersion
,
IN
EFI_GET_MEMORY_MAP
GetMemoryMap
OPTIONAL
,
IN
OUT
UINTN
*
TopMemory
OPTIONAL
)
{
EFI_STATUS
Status
;
*
MemoryMapSize
=
0
;
*
MemoryMap
=
NULL
;
if
(
GetMemoryMap
==
NULL
)
{
GetMemoryMap
=
gBS
->
GetMemoryMap
;
}
Status
=
GetMemoryMap
(
MemoryMapSize
,
*
MemoryMap
,
MapKey
,
DescriptorSize
,
DescriptorVersion
);
if
(
Status
!=
EFI_BUFFER_TOO_SMALL
)
{
DEBUG
((
DEBUG_INFO
,
"OCMM: Insane GetMemoryMap %r
\n
"
,
Status
));
return
Status
;
}
do
{
//
// This is done because extra allocations may increase memory map size.
//
*
MemoryMapSize
+=
512
;
//
// Requested to allocate from top via pages.
// This may be needed, because the pool memory may collide with the kernel.
//
if
(
TopMemory
!=
NULL
)
{
*
MemoryMap
=
(
EFI_MEMORY_DESCRIPTOR
*
)(
UINTN
)
BASE_4GB
;
*
TopMemory
=
EFI_SIZE_TO_PAGES
(
*
MemoryMapSize
);
Status
=
AllocatePagesFromTop
(
EfiBootServicesData
,
*
TopMemory
,
(
EFI_PHYSICAL_ADDRESS
*
)
MemoryMap
,
GetMemoryMap
,
NULL
);
if
(
EFI_ERROR
(
Status
))
{
DEBUG
((
DEBUG_INFO
,
"OCMM: Temp memory map allocation from top failure - %r
\n
"
,
Status
));
*
MemoryMap
=
NULL
;
return
Status
;
}
}
else
{
*
MemoryMap
=
AllocatePool
(
*
MemoryMapSize
);
if
(
*
MemoryMap
==
NULL
)
{
DEBUG
((
DEBUG_INFO
,
"OCMM: Temp memory map direct allocation failure
\n
"
));
return
EFI_OUT_OF_RESOURCES
;
}
}
Status
=
GetMemoryMap
(
MemoryMapSize
,
*
MemoryMap
,
MapKey
,
DescriptorSize
,
DescriptorVersion
);
if
(
EFI_ERROR
(
Status
))
{
if
(
TopMemory
!=
NULL
)
{
gBS
->
FreePages
(
(
EFI_PHYSICAL_ADDRESS
)
*
MemoryMap
,
*
TopMemory
);
}
else
{
FreePool
(
*
MemoryMap
);
}
*
MemoryMap
=
NULL
;
}
}
while
(
Status
==
EFI_BUFFER_TOO_SMALL
);
if
(
Status
!=
EFI_SUCCESS
)
{
DEBUG
((
DEBUG_INFO
,
"OCMM: Failed to obtain memory map - %r
\n
"
,
Status
));
}
return
Status
;
}
VOID
ShrinkMemoryMap
(
IN
OUT
UINTN
*
MemoryMapSize
,
IN
OUT
EFI_MEMORY_DESCRIPTOR
*
MemoryMap
,
IN
UINTN
DescriptorSize
)
{
UINTN
SizeFromDescToEnd
;
UINT64
Bytes
;
EFI_MEMORY_DESCRIPTOR
*
PrevDesc
;
EFI_MEMORY_DESCRIPTOR
*
Desc
;
BOOLEAN
CanBeJoined
;
BOOLEAN
HasEntriesToRemove
;
PrevDesc
=
MemoryMap
;
Desc
=
NEXT_MEMORY_DESCRIPTOR
(
PrevDesc
,
DescriptorSize
);
SizeFromDescToEnd
=
*
MemoryMapSize
-
DescriptorSize
;
*
MemoryMapSize
=
DescriptorSize
;
HasEntriesToRemove
=
FALSE
;
while
(
SizeFromDescToEnd
>
0
)
{
Bytes
=
EFI_PAGES_TO_SIZE
(
PrevDesc
->
NumberOfPages
);
CanBeJoined
=
FALSE
;
if
(
Desc
->
Attribute
==
PrevDesc
->
Attribute
&&
PrevDesc
->
PhysicalStart
+
Bytes
==
Desc
->
PhysicalStart
)
{
//
// It *should* be safe to join this with conventional memory, because the firmware should not use
// GetMemoryMap for allocation, and for the kernel it does not matter, since it joins them.
//
CanBeJoined
=
(
Desc
->
Type
==
EfiBootServicesCode
||
Desc
->
Type
==
EfiBootServicesData
||
Desc
->
Type
==
EfiConventionalMemory
||
Desc
->
Type
==
EfiLoaderCode
||
Desc
->
Type
==
EfiLoaderData
)
&&
(
PrevDesc
->
Type
==
EfiBootServicesCode
||
PrevDesc
->
Type
==
EfiBootServicesData
||
PrevDesc
->
Type
==
EfiConventionalMemory
||
PrevDesc
->
Type
==
EfiLoaderCode
||
PrevDesc
->
Type
==
EfiLoaderData
);
}
if
(
CanBeJoined
)
{
//
// Two entries are the same/similar - join them
//
PrevDesc
->
Type
=
EfiConventionalMemory
;
PrevDesc
->
NumberOfPages
+=
Desc
->
NumberOfPages
;
HasEntriesToRemove
=
TRUE
;
}
else
{
//
// Cannot be joined - we need to move to next
//
*
MemoryMapSize
+=
DescriptorSize
;
PrevDesc
=
NEXT_MEMORY_DESCRIPTOR
(
PrevDesc
,
DescriptorSize
);
if
(
HasEntriesToRemove
)
{
//
// Have entries between PrevDesc and Desc which are joined to PrevDesc,
// we need to copy [Desc, end of list] to PrevDesc + 1
//
CopyMem
(
PrevDesc
,
Desc
,
SizeFromDescToEnd
);
Desc
=
PrevDesc
;
HasEntriesToRemove
=
FALSE
;
}
}
Desc
=
NEXT_MEMORY_DESCRIPTOR
(
Desc
,
DescriptorSize
);
SizeFromDescToEnd
-=
DescriptorSize
;
}
}
EFI_STATUS
AllocatePagesFromTop
(
IN
EFI_MEMORY_TYPE
MemoryType
,
IN
UINTN
Pages
,
IN
OUT
EFI_PHYSICAL_ADDRESS
*
Memory
,
IN
EFI_GET_MEMORY_MAP
GetMemoryMap
,
IN
CHECK_ALLOCATION_RANGE
CheckRange
OPTIONAL
)
{
EFI_STATUS
Status
;
UINTN
MemoryMapSize
;
EFI_MEMORY_DESCRIPTOR
*
MemoryMap
;
UINTN
MapKey
;
UINTN
DescriptorSize
;
UINT32
DescriptorVersion
;
EFI_MEMORY_DESCRIPTOR
*
MemoryMapEnd
;
EFI_MEMORY_DESCRIPTOR
*
Desc
;
Status
=
GetCurrentMemoryMapAlloc
(
&
MemoryMapSize
,
&
MemoryMap
,
&
MapKey
,
&
DescriptorSize
,
&
DescriptorVersion
,
GetMemoryMap
,
NULL
);
if
(
EFI_ERROR
(
Status
))
{
return
Status
;
}
Status
=
EFI_NOT_FOUND
;
MemoryMapEnd
=
NEXT_MEMORY_DESCRIPTOR
(
MemoryMap
,
MemoryMapSize
);
Desc
=
PREV_MEMORY_DESCRIPTOR
(
MemoryMapEnd
,
DescriptorSize
);
for
(
;
Desc
>=
MemoryMap
;
Desc
=
PREV_MEMORY_DESCRIPTOR
(
Desc
,
DescriptorSize
))
{
//
// We are looking for some free memory descriptor that contains enough
// space below the specified memory.
//
if
(
Desc
->
Type
==
EfiConventionalMemory
&&
Pages
<=
Desc
->
NumberOfPages
&&
Desc
->
PhysicalStart
+
EFI_PAGES_TO_SIZE
(
Pages
)
<=
*
Memory
)
{
//
// Free block found
//
if
(
Desc
->
PhysicalStart
+
EFI_PAGES_TO_SIZE
((
UINTN
)
Desc
->
NumberOfPages
)
<=
*
Memory
)
{
//
// The whole block is under Memory: allocate from the top of the block
//
*
Memory
=
Desc
->
PhysicalStart
+
EFI_PAGES_TO_SIZE
((
UINTN
)
Desc
->
NumberOfPages
-
Pages
);
}
else
{
//
// The block contains enough pages under Memory, but spans above it - allocate below Memory
//
*
Memory
=
*
Memory
-
EFI_PAGES_TO_SIZE
(
Pages
);
}
//
// Ensure that the found block does not overlap with the restricted area.
//
if
(
CheckRange
!=
NULL
&&
CheckRange
(
*
Memory
,
EFI_PAGES_TO_SIZE
(
Pages
)))
{
continue
;
}
Status
=
gBS
->
AllocatePages
(
AllocateAddress
,
MemoryType
,
Pages
,
Memory
);
break
;
}
}
FreePool
(
MemoryMap
);
return
Status
;
}
Library/OcMemoryLib/OcMemoryLib.inf
浏览文件 @
bed4ffe1
...
...
@@ -42,6 +42,6 @@
OcStringLib
[Sources]
Get
MemoryMap.c
MemoryMap.c
LegacyRegionLock.c
LegacyRegionUnLock.c
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录