Skip to main content
The Qualcomm® Linux kernel baseline supports all memory management features and allocators. The following information outlines customizing the memory map and performing heap management. For more information about Linux kernel memory management, see Memory management. Memory map Memory map describes the areas that are reserved for subsystems, such as modem, camera, aDSP, and cDSP during kernel boot. The memory map sets no-map for the carved out regions in the DTSI, making them inaccessible to the kernel. Configurable carved-out regions are defined in the arch/arm64/boot/dts/qcom/kodiak.dtsi file under the reserved-memory node.
reserved-memory {
               cdsp_secure_heap_mem: cdsp-secure-heap@81800000 {
                        reg = <0x0 0x81800000 0x0 0x1e00000>;
                        no-map;
               };

               camera_mem: camera@84300000 {
                        reg = <0x0 0x84300000 0x0 0x500000>;
                        no-map;
               };

               wpss_mem: wpss@0x84800000 {
                        reg = <0x0 0x84800000 0x0 0x1900000>;
                        no-map;
               };

               adsp_mem: adsp@86100000 {
                        reg = <0x0 0x86100000 0x0 0x2800000>;
                        no-map;
               };
};
For Qualcomm SoCs, see the SoC-specific Qualcomm DTSI files to get this information.
The following early boot log shows carved out region creation for different subsystems:
[    0.000000] OF: reserved mem: 0x0000000081800000..0x00000000835fffff (30720 KiB) nomap non-reusable cdsp-secure-heap@81800000
[    0.000000] OF: reserved mem: 0x0000000084300000..0x00000000847fffff (5120 KiB) nomap non-reusable camera@84300000
[    0.000000] OF: reserved mem: 0x0000000084800000..0x00000000860fffff (25600 KiB) nomap non-reusable wpss@0x84800000
[    0.000000] OF: reserved mem: 0x0000000086100000..0x00000000888fffff (40960 KiB) nomap non-reusable adsp@86100000

Contiguous memory allocator

Qualcomm Linux distribution supports CMA to allocate large physically contiguous memory. CMA reserves a large physically contiguous memory area at boot time and provides physically continuous memory to CMA allocation. When not in use, CMA memory is available to the kernel buddy allocator for movable allocations. To change the size of the default CMA region, run cma=size_in_MB in the kernel command-line arguments. For more information on how to use the kernel parameter, see the following example:
cma=nn[MG]@[start[MG][-end[MG]]]
                        [KNL,CMA]
                        Sets the size of kernel global memory area for
                        contiguous memory allocations and optionally the
                        placement constraint by the physical address range of
                        memory allocations. A value of 0 disables CMA
                        altogether. For more information, see
                        kernel/dma/contiguous.c
The custom CMA regions are defined under the reserved-memory node with a shared-dma-pool compatible tag indicating the CMA region:
adsp_heap_mem: adsp-heap {
                        compatible = "shared-dma-pool";
                        alloc-ranges = <0x0 0x00000000 0x0 0xffffffff>;
                        reusable;
                        alignment = <0x0 0x400000>;
                        size = <0x0 0xc00000>;
               };
The following is the sample log for an aDSP CMA memory region reserved on boot:
[    0.000000] OF: reserved mem: initialized node adsp-heap, compatible id shared-dma-pool
[    0.000000] OF: reserved mem: 0x00000000ff000000..0x00000000ffbfffff (12288 KiB) map reusable adsp-heap

Supported heaps

The following table lists the heaps that are supported by default on the Qualcomm Linux distribution: Table: Default supported heaps
Heap nameDev nodeDescriptionUsage
System/dev/dma_heap/systemThe kernel creates the default DMA-BUF heap.All generic use cases must follow the system heap that uses the common Linux memory management buddy allocator underneath.
Reserved/dev/dma_heap/reservedThe default CMA-type heap created in the system uses the default reserved CMA region.If you need contiguous memory due to any constraints, use the CMA heap.

Use DMA-BUF heaps

DMA-BUF heaps are supported on the Qualcomm Linux distribution to assign custom CMA heaps. With DMA-BUF heaps, a device file is present for each heap in the /dev/dma_heap file system. Apart from the system heap and the common CMA reserved heap, you can create your own CMA-type DMA-BUF heaps. The following is a sample program that demonstrates how to use the DMA-BUF system heap created by the Qualcomm Linux kernel in /dev/dma_heap/system:
include <stdio.h>
include <stdlib.h>
include <fcntl.h>
include <errno.h>
include <unistd.h>
include <sys/ioctl.h>
include <linux/dma-buf.h>
#include <linux/dma-heap.h>

define DMA_HEAP_NAME "system"
define SZ_4 0x00000004  // to allocate a 4K buffer

int main()
{
int fd, dma_buf_fd;

struct dma_heap_allocation_data dma_alloc_data = {
   .len = SZ_4,
   .fd_flags = O_RDWR | O_CLOEXEC,
};

struct dma_buf_sync sync_start = {
   .flags = DMA_BUF_SYNC_START,
};
struct dma_buf_sync sync_end = {
   .flags = DMA_BUF_SYNC_END,
};

fd = open("/dev/dma_heap/system", O_RDWR);
if (fd < 0) {
   perror("open");
   return errno;
}

dma_buf_fd = ioctl(fd, DMA_HEAP_IOCTL_ALLOC, &dma_alloc_data);
if (dma_buf_fd < 0) {
   perror("ioctl");
   return errno;
}
printf("Allocated DMA buffer with fd %d\n", dma_buf_fd);

if (ioctl(dma_buf_fd, DMA_BUF_IOCTL_SYNC, &sync_start)) {
   perror("ioctl DMA_BUF_IOCTL_SYNC start");
   return errno;
}

//        Do something with the buffer here

if (ioctl(dma_buf_fd, DMA_BUF_IOCTL_SYNC, &sync_end))
{
   perror("ioctl DMA_BUF_IOCTL_SYNC end");
   return errno;
}

if (close(dma_buf_fd)) {
   perror("close");
   return errno;
}

if (close(fd)) {
   perror("close");
   return errno;
}

return 0;
}

Configure ZRAM as a swap device

ZRAM is a compressed swap mechanism that creates a virtual block device in RAM. ZRAM is enabled as a module within the kernel defconfig. ZRAM is configured in the Yocto build in the recipes-extended/zram/zram/zram-swap-init-update file. To enable or configure ZRAM, do the following:
# check if zram module is loaded
  lsmod | grep zram

# else load it
  modprobe zram

# Configure /dev/zram0 size according to your RAM size
  echo 128M > /sys/block/zram0/disksize

# activate swap
  mkswap /dev/zram0
  swapon /dev/zram0
To configure ZRAM as a swap device, see zram: Compressed RAM-based block devices.

Extend the memory map

To extend the memory map, adjust the addresses and sizes of memory regions in a DTSI file. Use the following information to extend the carved out regions: Add the carved out region in the arch/arm64/boot/dts/qcom/<SoC>-<board>-<variant>.dts file in the reserved-memory node using the following syntax:
my_carveout_mem: my_carveout_mem@address {
      reg= <0x0 0xbase_address 0x0 0xsize>;
      no-map;
}
For example:
my_carveout_mem: my_carveout_mem@d0800000 {
      reg= <0x0 0xd0800000 0x0 0x100000>;
      no-map;
}
Table: Syntax for carved out region
VariableDescription
my_carveout_mem@d0800000Indicates the name of the device node. The convention mandates that you append the base address of the memory region to the name.
my_carveout_memIndicates the label assigned to this node that can be used to reference this node from within the other nodes in the device tree using phandles.
regIndicates the property, which is a 64‑bit value that defines the base and size of the memory region.
no-mapIndicates that this region is carved out and the kernel should remove the mapping from its addressable range.
  • None of the regions should overlap. If you must increase a region size, shift all other subsequent regions, and configure them in the device tree to avoid overlapping.
  • The kernel expects all memory region boundaries defined for kernel usage to be 1 MB.
  • Existing carved out regions are protected by trusted firmware from kernel access. Decreasing their size or deleting them may result in an external abort, leading to a kernel crash.
Add CMA region To add the CMA region in the arch/arm64/boot/dts/qcom/<SoC>-<board>-<variant>.dts file under reserved-memory node, use the following syntax:
my_cma_mem: my_cma {
   compatible = "shared-dma-pool";
   alloc-ranges = <0x0 0x00000000 0x0 0xffffffff>;
   reusable;
   alignment = <0x0 0x400000>;
   size = <0x0 0x1400000>;
};
Table : Syntax for adding CMA region
ParametersDescription
my_cma_memLabel for the CMA node and can be accessed as a phandle. The label my_cma is the name of the CMA region.
shared-dma-poolIndicates that this region is a CMA area.
alloc-rangesIndicates if the region should be within a certain memory limit, as some devices can not access memory regions beyond the 32‑bit address limit.
reusableIndicates that the kernel can use the memory in this region when it’s free.
alignmentIndicates any alignment requirements in this region.
sizeIndicates the size of the region.
regThis is an optional attribute that indicates the fixed region for memory allocation, in the absence of which memory is dynamically allocated at a random address.