MC6*_*020 2 memory configuration bios x86 linux-kernel
由于至少是 2.6 内核,Kconfig 提供了选项 CONFIG_X86_RESERVE_LOW,描述为“为 BIOS 保留的低内存量,以千字节为单位”。(从我理解的物理地址 0 开始,范围从 4K 到 640K)
在我的系统上启动时,我的日志在启动过程即将开始时通知我:
BIOS-provided physical RAM map:
BIOS-e820: [mem 0x0000000000000000-0x000000000009ebff] usable
Run Code Online (Sandbox Code Playgroud)
从中我推断 BIOS 告诉内核内存的第一个 0x9ebff (~640K) 字节是可用的。(未预留)
进一步几行,我可以阅读:
e820: update [mem 0x00000000-0x00000fff] usable ==> reserved
Run Code Online (Sandbox Code Playgroud)
我理解我的设置的结果:CONFIG_X86_RESERVE_LOW = 4K
但是,考虑到 BIOS 本身断言 0-0x9ebff 范围是可用的,内核为 BIOS“保留”任何<~640K 的低内存量有什么意义?
您应该会看到此配置选项的更长帮助文本。它提供了两个原因。
config X86_RESERVE_LOW
int "为 BIOS 保留的低内存量,以千字节为单位"
默认 64
范围 4 640
帮助指定为 BIOS 保留的低内存量。
第一个页面包含内核不得使用的 BIOS 数据结构,因此必须始终保留该页面。
[剪辑]
代码中有类似的注释:
* A special case is the first 4Kb of memory;
* This is a BIOS owned area, not kernel ram, but generally
* not listed as such in the E820 table.
Run Code Online (Sandbox Code Playgroud)
传统的 BIOS 将使用前 1280 个字节 (0x500)。Linux 以 MMU 页大小(4096 字节)为单位分配 RAM。 OSDev指出——
在调用了所有 BIOS 函数之后,并且您的内核已加载到内存中的某处,引导加载程序或内核可能会永远退出实模式(通常通过进入 32 位保护模式)。如果内核不再使用实模式,那么 PC 中前 0x500 字节的内存可能会被重用和覆盖。
Linux 通常无法调用 BIOS。然而,它可能会在一些可怕的时刻这样做:提前启动、关闭和从睡眠模式恢复。如果您的系统是使用 UEFI 启动的,那么就 Linux 而言,没有它可以调用的 BIOS。
此外,保留第一页意味着成功的物理内存分配永远不会返回值 0。C 编程传统上保留地址 0 来表示“空指针”。我们可以在memblock_phys_alloc_range() 中看到这一点。在这一点上,改变似乎不太可能回报努力(和风险:-)。
* Return: physical address of the allocated memory block on success,
* %0 on failure.
*/
phys_addr_t __init memblock_phys_alloc_range(
Run Code Online (Sandbox Code Playgroud)
这是第二个原因:
默认情况下,我们保留物理 RAM 的前 64K,因为已知许多 BIOS 在挂起/恢复或监视器电缆插入等事件期间会破坏该内存范围,因此内核不得使用它。
如果您绝对相信 BIOS 能够正确地获得其所有内存预留和使用,则可以将其设置为 4。如果您知道您的 BIOS 有超出默认 64K 区域的问题,您可以将其设置为 640 以避免使用整个低内存范围。
如果您对 BIOS 有疑问(例如,在某些硬件热插拔事件后挂起/恢复不起作用或内核崩溃),那么您可能需要启用 X86_CHECK_BIOS_CORRUPTION=y 以允许内核检查典型的损坏模式。
如果您不确定,请将其保留为默认值 64。
最安全的假设是这也适用于 UEFI 固件,就像适用于 BIOS :-)。
从 v3.9 开始,内核日志消息中不再显示额外的低预留。它也没有显示在/proc/iomem. 内核只显示保留的第一个 4k,即使剩余的内存仍应保留。它只是没有添加到 e820 地图中。它被添加到不同的列表中。此更改的补丁在这里:x86,mm:在初始化稍后移动保留低内存。
如果你想了解更多关于额外预订的信息,以及需要它的悲惨故事,这里是补丁信息:
x86:为 AMI BIOS 添加 DMI 怪癖,在恢复期间损坏地址 0xc000
Alan Jenkins 和 Andy Wettstein 报告了一个暂停/恢复内存损坏错误,并在此处详细记录:
http://bugzilla.kernel.org/show_bug.cgi?id=11237
错误是 BIOS 覆盖了 0xc000 物理内存的 1K 内存,而没有将其注册为保留在 e820 中,也没有让内核对此有任何想法。
检测AMI BIOSen并保留1K。
我们用非常广泛的笔刷来描绘这个错误(在所有 AMI BIOS 系统上保留 1K),因为这个错误极难找到,需要数周时间以及大量的调试和修补。
该错误是通过 CONFIG_X86_CHECK_BIOS_CORRUPTION=y 调试功能发现的,如果怀疑存在类似的错误,则可以在其他系统上启用此功能以及扫描低内存以查找损坏的内存。
x86:添加 X86_RESERVE_LOW_64K
这个bugzilla:
http://bugzilla.kernel.org/show_bug.cgi?id=11237
记录了各种系统,其中 BIOS 在挂起/恢复和其他硬件事件期间使用前 64K 物理内存。
目前,我们在所有 AMI 和 Phoenix BIOS 系统上保留此内存。生命太短暂,无法像这样寻找微妙的内存损坏问题,因此我们默认情况下尝试保持健壮。
尽管如此,还是允许它被覆盖:允许希望内核可用的前 64K 内存的用户禁用这个怪癖,通过 CONFIG_X86_RESERVE_LOW_64K=n。
x86、bios:默认情况下,为所有 BIOS 保留低 64K
需要保留低 64K 的 BIOS 清单越来越长,因此将其设为所有 BIOS 的默认值。这也可以简化代码,并与第一个 4K 的保留代码统一。
这解决了内核 bugzilla 16661,谁知道还有什么...
错误 16661 - 低内存损坏
[...] 这意味着我们应该将他的 BIOS(请提供 dmidecode 信息)添加到 arch/x86/kernel/setup.c 中的 bad_bios_dmi_table 黑名单中。然而,底线是 64K 的内存量如此之小,而且该列表现在涵盖了如此多的现有 BIOS,我们应该无条件地使用它。
据我所知,Windows 7 实际上保留了 1 MiB 以下的所有内存以避免 BIOS 错误。
| 归档时间: |
|
| 查看次数: |
766 次 |
| 最近记录: |