从 GRUB2 多重引导信息结构中获取总可用 RAM
Get total avaiable RAM from the GRUB2 multiboot info structure
我设法访问了我的 i386 内核中的 GRUB 多重引导信息结构 (multiboot_info_t
),其中有两个字段分别称为 mem_lower
和 mem_upper
。我如何使用它们来获取总可用 RAM(以字节为单位)?
简单地说,你不能。
mem_lower
和mem_upper
是废弃字段,参考conventional memory and the extended memory。
引用 specifications:
If bit 0 in the flags
word is set, then the mem_*
fields are valid.
mem_lower
and mem_upper
indicate the amount of lower and upper memory, respectively, in kilobytes kibibytes.
Lower memory starts at address 0, and upper memory starts at address 1 megabyte mebibyte. The maximum possible value for lower memory is 640 kilobytes kibibytes.
The value returned for upper memory is maximally the address of the first upper memory hole minus 1 megabyte mebibyte. It is not guaranteed to be this value.
这段摘录的两个关键方面是:
- 在访问
mem_*
字段之前需要测试flags
字段。
mem_lower
和mem_upper
字段对内存空洞的处理非常糟糕。特别是 mem_upper
保存扩展内存的第一个连续块的大小,直到第一个孔。
第二点很重要,值得进一步讨论。
虽然可以访问内存本身,但在内存控制器级别 1,作为一个连续的块,它在内存子系统级别(曾经是 north-bridge and now is the uncore)是不连续的。
内存子系统在分配给内存的连续地址范围内创建 holes,方法是简单地不回收特定的子范围——从而浪费该内存——或者通过将子范围移动到更高的地址。
这种看似奇怪的行为背后的原因深深植根于 IBM PC 的历史演变。
完整的讨论超出了主题,但可以列出一个简短的版本。
最初,IBM 保留了 1MiB 地址 space 的前 640KiB 用于常规内存,其余 384KiB 用于映射 ROM - 包括 BIOS ROM。
请注意,内存控制器不得响应超过 640KiB 的 read/write 访问,以便它们访问 ROM。
当 1MiB 障碍被打破时(随意包括或不包括 HMA),从 640KiB 到 1MiB 的范围不能用于向后兼容。
这创建了第一个孔:标准孔。
286 只有一个 24 位地址总线,因此一个 16MiB 地址 space.
同时,ISA bus had already won against the MCA bus又发生在IBM PC兼容硬件上。
一些ISA扩展卡自带扩展ROM,标准孔用完了,16MiB地址末尾预留了1MiB孔space.
我称这个洞为 ISA hole.
从 32 位系统过渡到 64 位系统时,PCI(e) 发生了几乎相同的事情,生成了 PCI hole。
除了这些漏洞之外,还有 read/writable 的内存范围,但携带了 BIOS 布置的宝贵信息 - 即 ACPI tables.
这样的范围不能被 OS 不小心覆盖,因此必须向它报告。
所有这一切都在 e820 service 中达到顶峰,而不是返回内存大小(根据上面的讨论,这是没有意义的)它 returns 一个 内存映射 由范围及其类型(可用、保留、可回收、不良、NVS)组成。
这也反映在 GRUB multiboot_info_t
结构字段 mmap_*
中,您应该使用它来代替 [=35] 中指示的 mem_lower
和 mem_upper
=].
1 DIMMs 是通过等级、库、列和行号访问的,但内存控制器通常使此寻址线性且连续。
我设法访问了我的 i386 内核中的 GRUB 多重引导信息结构 (multiboot_info_t
),其中有两个字段分别称为 mem_lower
和 mem_upper
。我如何使用它们来获取总可用 RAM(以字节为单位)?
简单地说,你不能。
mem_lower
和mem_upper
是废弃字段,参考conventional memory and the extended memory。
引用 specifications:
If bit 0 in the
flags
word is set, then themem_*
fields are valid.
mem_lower
andmem_upper
indicate the amount of lower and upper memory, respectively, inkilobyteskibibytes.Lower memory starts at address 0, and upper memory starts at address 1
megabytemebibyte. The maximum possible value for lower memory is 640kilobyteskibibytes.The value returned for upper memory is maximally the address of the first upper memory hole minus 1
megabytemebibyte. It is not guaranteed to be this value.
这段摘录的两个关键方面是:
- 在访问
mem_*
字段之前需要测试flags
字段。 mem_lower
和mem_upper
字段对内存空洞的处理非常糟糕。特别是mem_upper
保存扩展内存的第一个连续块的大小,直到第一个孔。
第二点很重要,值得进一步讨论。
虽然可以访问内存本身,但在内存控制器级别 1,作为一个连续的块,它在内存子系统级别(曾经是 north-bridge and now is the uncore)是不连续的。
内存子系统在分配给内存的连续地址范围内创建 holes,方法是简单地不回收特定的子范围——从而浪费该内存——或者通过将子范围移动到更高的地址。
这种看似奇怪的行为背后的原因深深植根于 IBM PC 的历史演变。
完整的讨论超出了主题,但可以列出一个简短的版本。
最初,IBM 保留了 1MiB 地址 space 的前 640KiB 用于常规内存,其余 384KiB 用于映射 ROM - 包括 BIOS ROM。
请注意,内存控制器不得响应超过 640KiB 的 read/write 访问,以便它们访问 ROM。
当 1MiB 障碍被打破时(随意包括或不包括 HMA),从 640KiB 到 1MiB 的范围不能用于向后兼容。
这创建了第一个孔:标准孔。
286 只有一个 24 位地址总线,因此一个 16MiB 地址 space.
同时,ISA bus had already won against the MCA bus又发生在IBM PC兼容硬件上。
一些ISA扩展卡自带扩展ROM,标准孔用完了,16MiB地址末尾预留了1MiB孔space.
我称这个洞为 ISA hole.
从 32 位系统过渡到 64 位系统时,PCI(e) 发生了几乎相同的事情,生成了 PCI hole。
除了这些漏洞之外,还有 read/writable 的内存范围,但携带了 BIOS 布置的宝贵信息 - 即 ACPI tables.
这样的范围不能被 OS 不小心覆盖,因此必须向它报告。
所有这一切都在 e820 service 中达到顶峰,而不是返回内存大小(根据上面的讨论,这是没有意义的)它 returns 一个 内存映射 由范围及其类型(可用、保留、可回收、不良、NVS)组成。
这也反映在 GRUB multiboot_info_t
结构字段 mmap_*
中,您应该使用它来代替 [=35] 中指示的 mem_lower
和 mem_upper
=].
1 DIMMs 是通过等级、库、列和行号访问的,但内存控制器通常使此寻址线性且连续。