How can I reserve a block of memory from the Linux kernel?

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"

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.


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: framebuffer@78000000 {
        reg = <0x78000000 0x800000>;
    };

    multimedia_reserved: multimedia@77000000 {
        compatible = "acme,multimedia-memory";
        reg = <0x77000000 0x4000000>;
    };
};