Linux 内核使用memmap
参数 *) 来手动指定不同用例的内存区域。
问: 有什么区别预订的内存 ( memmap=nn[KMG]$ss[KMG]
) 和受保护的记忆 (memmap=nn[KMG]!ss[KMG]
)?
即内核如何处理它们以及何时使用它们?
关于/proc/iomem
,我认为保留内存被列为Reserved
,受保护内存被列为RAM buffer
。那是对的吗?
*)我发现没有好的可链接参考页面不是文字墙,所以我附加了来自内核文档:
memmap=exactmap [KNL,X86] Enable setting of an exact
E820 memory map, as specified by the user.
Such memmap=exactmap lines can be constructed based on
BIOS output or other requirements. See the memmap=nn@ss
option description.
memmap=nn[KMG]@ss[KMG]
[KNL] Force usage of a specific region of memory.
Region of memory to be used is from ss to ss+nn.
If @ss[KMG] is omitted, it is equivalent to mem=nn[KMG],
which limits max address to nn[KMG].
Multiple different regions can be specified,
comma delimited.
Example:
memmap=100M@2G,100M#3G,1G!1024G
memmap=nn[KMG]#ss[KMG]
[KNL,ACPI] Mark specific memory as ACPI data.
Region of memory to be marked is from ss to ss+nn.
memmap=nn[KMG]$ss[KMG]
[KNL,ACPI] Mark specific memory as reserved.
Region of memory to be reserved is from ss to ss+nn.
Example: Exclude memory from 0x18690000-0x1869ffff
memmap=64K$0x18690000
or
memmap=0x10000$0x18690000
Some bootloaders may need an escape character before '$',
like Grub2, otherwise '$' and the following number
will be eaten.
memmap=nn[KMG]!ss[KMG]
[KNL,X86] Mark specific memory as protected.
Region of memory to be used, from ss to ss+nn.
The memory region may be marked as e820 type 12 (0xc)
and is NVDIMM or ADR memory.
memmap=<size>%<offset>-<oldtype>+<newtype>
[KNL,ACPI] Convert memory within the specified region
from <oldtype> to <newtype>. If "-<oldtype>" is left
out, the whole region will be marked as <newtype>,
even if previously unavailable. If "+<newtype>" is left
out, matching memory will be removed. Types are
specified as e820 types, e.g., 1 = RAM, 2 = reserved,
3 = ACPI, 12 = PRAM.
答案1
预订的内存是内核出于某种原因不能/不应该用作常规内存的内存。
受保护内存(有时也称为持久记忆)是保证在重新启动或断电后保留其内容的内存,因为它是非易失性 DIMM (NVDIMM)或出于其他原因。
e820 类型 12 很难解释,因为在 ACPI 6.0 之前的某些系统中,它用于指示 NVDIMM,即受保护/持久内存,但 ACPI 6.0 将其定义为类型 7,并将类型 12 重新定义为“OEM 保留”。
内核中的注释拱门/x86/include/asm/e820/types.h表示一些较旧的系统也使用类型 6 来表示受保护/持久内存,即早期的 NVDIMM 支持是特定于供应商的混乱,直到 ACPI 6.0 提供新定义(并重新定义旧定义以表示“不要碰这个混乱”) )。
Linux 显然会忽略 e820 type 12 内存的持久性功能,除非CONFIG_X86_PMEM_LEGACY=y
设置了 。
答案2
这只是部分答案。通过测试,我了解到:
对于 Linux 命令行,例如:(memmap=0x8000000$0x1d000000
请注意,对于 grub,您需要在 grub.conf: 中引用它memmap=0x8000000\$0x1d000000
),您会在引导过程中看到以下行:
reserve setup_data: [mem 0x000000001d000000-0x0000000024ffffff] reserved
对于 linux 命令行:memmap=0x8000000!0x1d000000
,您会在启动过程中看到以下行:
reserve setup_data: [mem 0x000000001d000000-0x0000000024ffffff] persistent (type 12)
添加内核命令行选项iomem=relaxed
后,预订的配置我能够访问/dev/mem
、mmap 和读/写0x1d000000
范围。当我使用受保护的配置,我无法通过访问它/dev/mem
(并且我确实收到一条消息:)x86/PAT: peek:9098 map pfn expected mapping type uncached-minus for [mem 0x1d000000-0x1d000fff], got write-back
。
有关此内容的更多间接相关信息,我发现Linux 内核 x86 PAT 文档。我想它内容丰富,但这也没有真正揭示受保护和保留之间的区别,但是看看这个有关 uncached-minus、mmap 和类似内容的更多信息的问题/答案。对于它的价值,/sys/kernel/debug/x86/pat_memtype_list
并/proc/mtrr
没有列出上面列出的映射预订的配置。
稍微相关一点,正如我上面所说的“持久(类型12)”,它解码为E820_TYPE_PRAM
(又名IORES_DESC_PERSISTENT_MEMORY_LEGACY
),“保留”为E820_TYPE_RESERVED
(又名IORES_DESC_RESERVED
)。更具体地说,在拱门/x86/内核/e820.c可以看到内核命令行的解析。
尽管有所有这些信息,我仍然没有从根本上理解其中的区别。也许最终有人可以回答这个问题。但也许这足以让人们解决他们遇到的任何问题。