I have a device that needs a block of memory that is reserved solely for it, without the OS intervening. Is there any way to tell BIOS or the OS that a block of memory is reserved, and it must not use it?
I am using this device on an openSUSE machine.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
If you want the OS to totally ignore it, you need to make a memory hole using “memmap.” See this reference. For example, if you want 512M at the 2GB barrier, you can put “memmap=512M$2G” on your kernel command line.
You will need to check your dmesg to find a contiguous hole to steal so you don’t stomp on any devices; that is specific to your motherboard+cards.
This is not the recommended way to do things – see Warren Young’s answer for how to properly do it (kernel drivers + DMA). I’m answering the exact question you asked. If you plan on making this for end users, they will hate you if you do this to them… trust me, that’s the only reason I knew this answer.
Edit: If you are using grub2 w/ grubby (e.g. CentOS 7), you need to make sure to escape the $. There should be a single before $. Example:
$ sudo -v $ sudo grubby --update-kernel=ALL --args=memmap='128M\$0x57EF0000' $ sudo grubby --info $(sudo grubby --default-kernel) | grep memmap args="ro crashkernel=auto ... memmap=128M$0x57EF0000"
Method 2
What you’re asking for is called DMA. You need to write a driver to reserve this memory.
Yes, I realize you said you didn’t want the OS to intervene, and a driver becomes part of the OS, but in absence of a driver’s reservation, the kernel believes all memory belongs to it. (Unless you tell the kernel to ignore the memory block, per Aaron’s answer, that is.)
Chapter 15 (PDF) of “Linux Device Drivers, 3/e” by Rubini, Corbet and Kroah-Hartmann covers DMA and related topics.
If you want an HTML version of this, I found the second-edition version of the chapter elsewhere online. Beware that the 2nd edition is over a decade old now, having come out when kernel 2.4 was new. There’s been a lot of work on the memory management subsystem of the kernel since those days, so it may not apply very well any more.
Method 3
To reserve a block of memory from the kernel in ARM based Linux, you can also use a reserved-memory node in your device tree (dts) file. In kernel documentation (see here), there is an example:
memory {
reg = <0x40000000 0x40000000>;
};
reserved-memory {
#address-cells = <1>;
#size-cells = <1>;
ranges;
/* global autoconfigured region for contiguous allocations */
linux,cma {
compatible = "shared-dma-pool";
reusable;
size = <0x4000000>;
alignment = <0x2000>;
linux,cma-default;
};
display_reserved: <a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="bddbcfdcd0d8dfc8dbdbd8cffd8a858d8d8d8d8d8d">[email protected]</a> {
reg = <0x78000000 0x800000>;
};
multimedia_reserved: <a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6f021a031b06020a0b060e2f58585f5f5f5f5f5f">[email protected]</a> {
compatible = "acme,multimedia-memory";
reg = <0x77000000 0x4000000>;
};
};
Method 4
First enter this command, to check your current setting:
sysctl vm.min_free_kbytes
To change the set value, edit /etc/sysctl.conf. Look for the line:
vm.min_free_kbytes=12888
If it doesn’t exist, create it (along with your desired value). The following values are acceptable:
8192 12288 16384 20480
8M is extremely conservative; it can sit at 16M comfortably. Once you change the value, run this and no reboot is needed:
sudo sysctl -p
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0