从 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_lowermem_upper。如何使用它们来获取可用 RAM 总量(以字节为单位)?

【问题讨论】:

【参考方案1】:

简单地说,你不能。

mem_lowermem_upper 是过时字段,指的是 conventional memory 和 extended memory。 引用specifications:

如果设置了flags字中的bit 0,则mem_*字段有效。mem_lowermem_upper表示低位和高位内存的数量,分别以千字节千字节为单位。

低位内存从地址0开始,高位内存从地址1开始兆字节兆字节。较低内存的最大可能值为 640 千字节 千字节。

上层内存返回的值最大是第一个上层内存孔的地址减去1 兆字节兆字节。不保证是这个值。

这段摘录的两个关键方面是:

    flags 字段需要在访问mem_* 字段之前进行测试。 mem_lowermem_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_lowermem_upper,如 OSDev wiki 中所示。


1DIMMs 是通过秩、组、列和行号访问的,但内存控制器通常使这种寻址线性且连续。

【讨论】:

以上是关于从 GRUB2 多重引导信息结构中获取总可用 RAM的主要内容,如果未能解决你的问题,请参考以下文章

移动硬盘安装grub2引导winpe,以后不需要格式化整个移动硬盘(本例移动硬盘亦可用u盘代替)

如何从源代码构建 grub2 引导加载程序并使用 qemu 模拟器对其进行测试

教程在UEFI启动方式下,通过GRUB2引导,直接从硬盘ISO文件安装Windows10和Ubuntu双系统

grub2和systemd

编译UEFI版本Grub2引导多系统文件efi

grub2添加gpt+efi的win7引导项