在 Linux 启动时尽早保留物理内存空间

Posted

技术标签:

【中文标题】在 Linux 启动时尽早保留物理内存空间【英文标题】:Reserving physical memory space as early as possible in Linux boot-time 【发布时间】:2016-04-20 13:35:05 【问题描述】:

我正在尝试找到一种方法,以便在系统启动后尽早为专有内存类型的硬件保留物理内存(带有 Intel Xeon 服务器平台的 Linux CentO)。

我在 arch/x86/kernel/setup.c 中的 setup_arch() 执行了以下操作,它可以工作,但发现我不允许修补内核。要求是没有 Bios 和内核模块。

setup_arch()
    
  ....
  // Calls a proprietary function that returns custom proprietary memory module's starting address and size. 

  memblock_reserve(mem_start_addr, mem_size);  
  .....
 

我也不能在 Grub 中使用 memmap=xx/xx,因为设备的启动和大小是未知的(它必须被软件“发现”)

有什么办法吗?

【问题讨论】:

我一直在为 20+ 编写 linux 内核/驱动程序,而且,IMO,“无补丁”要求是,嗯,很傻......在这种情况下 [专用硬件]。好的,所以没有对setup_arch 的补丁,但是添加一个“内置”的驱动程序/模块怎么样(即直接编译到内核中——不可动态加载)。许多模块/驱动程序都是以这种方式构建的。如果您 [仍然] 做不到,我会严重质疑该要求的合理性,除非有 真正 充分的理由 [而且我很乐意听到它]。 有一个叫做mem的内核参数可以用来指定内核可以使用的内存大小。您可以通过提供较小的mem 来保留一些物理内存。 克雷格,“我也想到了“内置”的驱动程序/模块,但驱动程序通常会在启动过程中加载很久。我们需要保护/保留linux 接触它之前的硬件内存空间,因为它可能会在硬件中产生未定义的行为。在此期间,内核启动到驱动程序,linux 有可能对该内存空间做一些事情。对吗? @electro 你有没有找到这个问题的答案?我正在努力实现与您相同的目标。我们有一个需要明确控制的设备,并且不希望 Linux 内核在任何时候都加载到这个内存空间中。你有什么推荐的? 【参考方案1】:

一个想法是编写一个自定义 grub 模块并使用它设置memmap=xx。 以下是如何做到的。

请注意,自 CentOS 6.x or below uses grub 0.9x 以来,以下方法仅适用于 CentOS 7 以上。 在这种情况下,您可能需要修改 grub 0.9x 的代码并替换 /boot/grub/stage1/boot/grub/stage2

$ git clone git://git.savannah.gnu.org/grub.git
$ cd grub
$ git checkout grub-2.02-beta2 # CentOS 7 currently uses grub-2.02-beta
$ vim grub-core/Makefile.core.def # add following row
module = 
    name = my_custom_module;
    common = lib/my_custom_module.c;
;

$ vim grub-core/lib/my_custom_module.c # create following file
#include <grub/dl.h>
#include <grub/env.h>

GRUB_MOD_LICENSE ("GPLv3+");

GRUB_MOD_INIT(my_custom_module)
    // Calls a proprietary function that returns custom proprietary memory module's starting address and size.
    const char *mem_size = "123";
    grub_env_set("my_memsize",mem_size);

GRUB_MOD_FINI(my_custom_module)

$ ./autogen.sh
$ ./configure
$ make

现在您可以发现grub-core/my_custom_module.mod 已创建。 所以把它复制到/boot/grub2/i386-pc/(或任何你的*.mod文件存在)

编辑 grub.conf 并添加类似的内容

insmod my_custom_module
linux /boot/vmlinuz-3.10.el7.x86_64 root=UUID=1a3b5c7d9 ro memmap=$my_memsize

【讨论】:

memmap 通常像 memmap=4G/$2G 一样使用,这意味着在 address=2G 处保留 4G 内存。那么,我是否需要在 grub.cfg 中创建一个字符串 "4G/$2G" memmap=string ?这样做的正确方法是什么? @electro 我认为您可以在 GRUB_MOD_INIT 中生成 char *the_string="4G/$2G" 并调用 grub_env_set("my_memsize",the_string)。使用该模块,grub.conf 中的$my_memsize 将替换为the_string

以上是关于在 Linux 启动时尽早保留物理内存空间的主要内容,如果未能解决你的问题,请参考以下文章

内存保留和提交

Linux内存体系及文件系统

linux增加swap空间

Linux内存机制(swap)

oracle数据库管理安装到物理内存交换空间时为啥失败?

物理内存和虚拟内存