从 GRUB2 多重引导信息结构中获取总可用 RAM
Posted
技术标签:
【中文标题】从 GRUB2 多重引导信息结构中获取总可用 RAM【英文标题】:Get total avaiable RAM from the GRUB2 multiboot info structure 【发布时间】:2018-01-14 18:13:59 【问题描述】:我设法访问了 i386 内核中的 GRUB 多重引导信息结构 (multiboot_info_t
),其中有两个字段分别称为 mem_lower
和 mem_upper
。如何使用它们来获取可用 RAM 总量(以字节为单位)?
【问题讨论】:
【参考方案1】:简单地说,你不能。
mem_lower
和 mem_upper
是过时字段,指的是 conventional memory 和 extended memory。
引用specifications:
如果设置了
flags
字中的bit 0,则mem_*
字段有效。mem_lower
和mem_upper
表示低位和高位内存的数量,分别以千字节千字节为单位。低位内存从地址0开始,高位内存从地址1开始
兆字节兆字节。较低内存的最大可能值为 640千字节千字节。上层内存返回的值最大是第一个上层内存孔的地址减去1
兆字节兆字节。不保证是这个值。
这段摘录的两个关键方面是:
flags
字段需要在访问mem_*
字段之前进行测试。
mem_lower
和mem_upper
字段对内存漏洞的处理非常糟糕。特别是mem_upper
将扩展内存的第一个连续块的大小保存到第一个孔。
第二点很重要,值得进一步讨论。 虽然可以访问内存本身,但在内存控制器级别1,作为一个连续块,它在内存子系统级别不是连续的(曾经是north-bridge,现在是uncore )。 内存子系统在分配给内存的连续地址范围中创建空洞,方法是简单地不回收特定的子范围 - 从而浪费该内存 - 或者通过将子范围移动到更高的地址。
这种看似奇怪的行为背后的原因深深植根于 IBM PC 的历史演变。 完整的讨论不在主题范围内,但可以列出一个简短的版本。 最初,IBM 为常规内存保留了 1MiB 地址空间中的前 640KiB,其余 384KiB 用于映射 ROM(包括 Bios ROM)。 请注意,内存控制器不得响应 640KiB 以上的读/写访问,以便它们访问 ROM。
当 1MiB 障碍被打破时(包括或不包括 HMA),从 640KiB 到 1MiB 的范围不能用于向后兼容。 这创建了第一个孔:标准孔。 286 只有一个 24 位地址总线,因此有 16MiB 的地址空间。 同时,ISA bus 已经战胜了MCA bus,并在 IBM PC 兼容硬件中进行。 一些 ISA 扩展卡带有扩展 ROM,标准孔已用尽,在 16MiB 地址空间的末尾保留了一个 1MiB 孔。 我把这个洞称为ISA hole。 从 32 位系统转换到 64 位系统时,PCI(e) 发生了几乎相同的事情,生成 PCI hole。
除了这些漏洞之外,还有一些内存范围可以读/写,但会携带 BIOS 设置的宝贵信息——即ACPI tables。 此类范围不能被操作系统随意覆盖,因此必须向其报告。
所有这一切都在e820 service 中达到顶峰,而不是返回内存大小(根据上面的讨论,这没有意义)它返回一个由范围及其类型组成的 内存映射 (可用、保留、可回收、坏、NVS)。
这也反映在 GRUB multiboot_info_t
结构字段 mmap_*
中,您应该使用它来代替 mem_lower
和 mem_upper
,如 OSDev wiki 中所示。
1DIMMs 是通过秩、组、列和行号访问的,但内存控制器通常使这种寻址线性且连续。
【讨论】:
以上是关于从 GRUB2 多重引导信息结构中获取总可用 RAM的主要内容,如果未能解决你的问题,请参考以下文章
移动硬盘安装grub2引导winpe,以后不需要格式化整个移动硬盘(本例移动硬盘亦可用u盘代替)
如何从源代码构建 grub2 引导加载程序并使用 qemu 模拟器对其进行测试