# 메모리 구성 및 관리

Qualcomm^®^ Linux 커널 기준은 모든 메모리 관리 기능 및 할당자를 지원합니다. 다음 정보는 메모리 맵을 사용자 지정하고 힙 관리를 수행하는 방법에 대해 개괄적으로 설명합니다.

Linux 커널 메모리 관리에 대한 자세한 내용은 [Memory management](https://www.kernel.org/doc/html/next/core-api/index.html#memory-management) 를 참조하세요.

**메모리 맵**

메모리 맵은 커널 부팅 시 모뎀, 카메라, aDSP, cDSP 같은 서브시스템을 위해 예약된 영역을 설명합니다.

메모리 맵은 DTSI 내의 분리된 영역에 `no-map` 을 설정하여 커널에 액세스할 수 없게 만듭니다.

구성 가능한 분리된 영역은 `reserved-memory` 노드 아래의 `arch/arm64/boot/dts/qcom/qcs6490.dtsi` 파일에 정의되어 있습니다.

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;
                   };
    };
    Copy to clipboard

참고

Qualcomm SoC의 경우 이러한 정보를 확인하려면 SoC별 Qualcomm DTSI 파일을 참조하세요.

다음 초기 부팅 로그는 다양한 서브시스템에 대한 분리된 영역 생성을 보여줍니다.

[    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
    Copy to clipboard

## 인접한 메모리 할당자

Qualcomm Linux 배포는 CMA를 지원하여 물리적으로 인접한 큰 메모리를 할당할 수 있습니다. CMA는 부팅 시 물리적으로 인접한 큰 메모리 영역을 할당하고, CMA 할당에 물리적으로 인접한 메모리를 제공합니다. 사용되지 않을 경우, 이동 가능한 할당을 위해 CMA 메모리가 커널 버디 할당자에게 제공됩니다.

기본 CMA 영역의 크기를 변경하려면 커널 명령줄 인자에서 `cma= =in_MB` 를 실행합니다. 커널 매개변수를 사용하는 방법에 대한 자세한 내용은 다음 예시를 참조하세요.

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
    Copy to clipboard

CMA 영역은 CMA 영역을 나타내는 `shared-dma-pool` 호환 태그가 있는 `reserved-memory` 노드 아래에 정의되어 있습니다.

adsp_heap_mem: adsp-heap {
                            compatible = "shared-dma-pool";
                            alloc-ranges = <0x0 0x00000000 0x0 0xffffffff>;
                            reusable;
                            alignment = <0x0 0x400000>;
                            size = <0x0 0xc00000>;
                   };
    Copy to clipboard

다음은 부팅 시 예약된 aDSP CMA 메모리 영역의 샘플 로그입니다.

[    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
    Copy to clipboard

### 사용자 지정 CMA 힙 추가

DMA-BUF 힙을 사용하여 사용자 지정 CMA 영역을 만들려면 Qualcomm Linux 커널의 기존 DMA-BUF 프레임워크를 사용하세요.

Qualcomm Linux 커널은 사용자 지정 DMA-BUF 힙을 위한 `cma_heap_add()` API를 내보냅니다.

/**
    * cma_heap_add - adds a CMA heap to dmabuf heaps
    * @cma:       pointer to the CMA pool to register the heap for
    * @data:      unused
    *
    * Returns 0 on success. Else, returns errno.
    */
    
    int cma_heap_add(struct cma *cma, void *data);
    Copy to clipboard

DMA-BUF 힙은 사용자 공간에 내보내기 되며 기기 트리에 있는 CMA 영역의 phandle과 같은 이름을 갖습니다.

사용자 지정 CMA 힙을 추가하려면 다음을 수행하세요.

1. 사용자 지정 CMA 영역을 만들려면 [인접한 메모리 할당자](https://docs.qualcomm.com/doc/80-70020-3KO/topic/memory.html#memory-contiguous) 를 참조하세요.
2. 사용자 지정 힙을 추가하는 드라이버에서 다음을 수행합니다.

    1. 새로 추가된 CMA 영역에 대한 기기 트리를 구문 분석합니다.
    2. 드라이버와 연관된 DMA-BUF 힙을 추가합니다.

int create_my_cma_heap(struct device *dev)
            {
               int rc = 0, idx = 0;
            
               rc = of_reserved_mem_device_init_by_idx(dev, dev->of_node, 0);  // Parse the devicetree for the cma region
            
               if (rc) {
                        pr_err("No reserved DMA memory, ret=%d\n", rc);
                        rc = -EINVAL;
                        goto err;
               }
            
               rc = cma_heap_add(dev->cma_area, NULL);  // Add a dmabuf heap associated with the cma region
            
               if (rc) {
                        pr_err("cma_heap_add failed, ret=%d\n", rc);
                        rc = -EINVAL;
                        goto err;
               }
            
            err:
               return rc;
            }
            Copy to clipboard

참고

페이지 마이그레이션을 지원하려면 CMA 영역을 4MB 주소 기반 및 크기에 맞게 정렬합니다. 마이그레이션은 2 ^pageblock\_order^ 페이지에서 페이지 블록 수준으로 이루어집니다. 페이지 블록 순서는 Qualcomm Linux 커널에서 10번째입니다.

### 지원되는 힙

다음 표에는 Qualcomm Linux 배포에서 기본적으로 지원되는 힙이 나열되어 있습니다.

표: 기본적으로 지원되는 힙

| 힙 이름 | Dev 노드 | 설명 | 사용 |
| --- | --- | --- | --- |
| 시스템 | /dev/dma_heap/system<br>    Copy to clipboard | 커널이 기본 DMA-BUF 힙을 생성합니다. | 모든 일반적인 사용 사례는 기본적으로 공통 Linux 메모리 관리 버디 할당자를 사용하는 시스템 힙을 따라야 합니다. |
| 예약됨 | /dev/dma_heap/reserved<br>    Copy to clipboard | 시스템에서 생성된 기본적인 CMA 타입 힙은 기본적인 *예약된* CMA 영역을 사용합니다. | 제약 조건이 있어 인접한 메모리가 필요한 경우, CMA 힙을 사용하세요. |
| 사용자 지정 CMA 힙 | /dev/dma_heap/my_cma_heap<br>    Copy to clipboard | 사용자 정의 CMA 유형 힙입니다. | 특정한 사용자 지정 CMA 하드웨어를 위한 고유한 CMA 유형 힙을 만들고 싶은 경우에 사용합니다. |

### DMA-BUF 힙 사용

DMA-BUF 힙은 사용자 지정 CMA 힙을 할당할 수 있도록 Qualcomm Linux 배포에서 지원됩니다. DMA-BUF 힙을 사용하면 `/dev/dma_heap` 파일 시스템 내의 각 스택에 대한 기기 파일이 존재하게 됩니다. 시스템 힙과 공통 CMA 예약 힙 외에도, 고유한 CMA 타입 DMA-BUF 힙을 만들 수 있습니다.

다음은 Qualcomm Linux 커널이 `/dev/dma_heap/system:` 에서 생성한 DMA-BUF 시스템 힙을 사용하는 방법을 보여주는 샘플 프로그램입니다.

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;
    }
    Copy to clipboard

### ZRAM을 스왑 기기로 구성

ZRAM은 RAM에 가상 블록 기기를 생성하는 압축된 스왑 메커니즘입니다. ZRAM은 커널 defconfig 내에서 모듈로 활성화되어 있습니다.

ZRAM은 `recipes-extended/zram/zram/zram-swap-init-update` 파일의 Yocto 빌드에 구성되어 있습니다.

ZRAM을 활성화하거나 구성하려면 다음 작업을 수행하세요.

# 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
    Copy to clipboard

ZRAM을 스왑 기기로 구성하려면 [zram: Compressed RAM-based block devices](https://www.kernel.org/doc/html/v6.6/admin-guide/blockdev/zram.html) 를 참조하세요.

### 메모리 맵 확장

메모리 맵을 확장하려면 DTSI 파일에서 메모리 영역의 주소와 크기를 조정하세요.

다음 정보를 사용하여 분리된 영역을 확장합니다.

다음 구문을 사용하여 **reserved-memory** 노드에 있는 `arch/arm64/boot/dts/qcom/<SoC>-<board>-<variant>.dts` 파일에 분리된 영역을 추가합니다.

my_carveout_mem: my_carveout_mem@address {
          reg= <0x0 0xbase_address 0x0 0xsize>;
          no-map;
    }
    Copy to clipboard

예시:

my_carveout_mem: my_carveout_mem@d0800000 {
          reg= <0x0 0xd0800000 0x0 0x100000>;
          no-map;
    }
    Copy to clipboard

표: 분리된 영역의 구문

| 변수 | 설명 |
| --- | --- |
| my_carveout_mem@d0800000<br>    Copy to clipboard | 기기 노드의 이름을 나타냅니다. 이 규칙에 따르면 메모리 영역의 기본 주소를 이름 뒤에 추가해야 합니다. |
| my_carveout_mem<br>    Copy to clipboard | 이 노드에 할당된 레이블을 나타냅니다. 해당 레이블은 phandles를 사용하여 기기 트리의 다른 노드 내에서 이 노드를 참조하는 데 사용할 수 있습니다. |
| reg<br>    Copy to clipboard | 메모리 영역의 기준과 크기를 정의하는 64비트 값인 속성을 나타냅니다. |
| no-map<br>    Copy to clipboard | 이 영역이 분리되었으며 커널은 주소 지정 가능한 범위에서 매핑을 제거해야 한다는 것을 나타냅니다. |

참고

- 영역 중 어느 영역도 겹치지 않아야 합니다. 영역 크기를 늘려야 할 경우, 그 밖의 모든 후속 영역을 이동한 후 겹치지 않도록 기기 트리에 영역을 구성하세요.
- 커널 기준에서, 커널 사용량을 위해 정의된 모든 메모리 영역 경계는 1MB여야 합니다.
- 기존의 분리된 영역은 신뢰할 수 있는 펌웨어로 보호되어 커널 액세스가 제한됩니다. 영역의 크기를 줄이거나 삭제하면 외부 중단이 발생할 수 있으며, 이는 커널 충돌로 이어질 수 있습니다.

**CMA 영역 추가**

다음 구문을 사용하여 **reserved-memory** 노드에 있는 `arch/arm64/boot/dts/qcom/<SoC>-<board>-<variant>.dts` 파일에 CMA 영역을 추가합니다.

my_cma_mem: my_cma {
       compatible = "shared-dma-pool";
       alloc-ranges = <0x0 0x00000000 0x0 0xffffffff>;
       reusable;
       alignment = <0x0 0x400000>;
       size = <0x0 0x1400000>;
    };
    Copy to clipboard

표: CMA 영역 추가를 위한 구문

| 매개변수 | 설명 |
| --- | --- |
| my_cma_mem<br>    Copy to clipboard | CMA 노드에 대한 레이블을 붙이며 phandle로 액세스할 수 있습니다. `my_cma` 라는 레이블은 CMA 영역의 이름입니다. |
| shared-dma-pool<br>    Copy to clipboard | 이 영역이 CMA 영역임을 나타냅니다. |
| alloc-ranges<br>    Copy to clipboard | 해당 영역이 특정 메모리 한도 이내여야 하는지 여부를 나타냅니다. 일부 기기는 32비트 주소 한도를 넘는 메모리 영역에 접근할 수 없기 때문입니다. |
| reusable<br>    Copy to clipboard | 가용 메모리가 있을 경우 커널이 이 영역의 메모리를 사용할 수 있음을 나타냅니다. |
| alignment<br>    Copy to clipboard | 이 영역의 모든 정렬 요구사항을 나타냅니다. |
| size<br>    Copy to clipboard | 영역의 크기를 나타냅니다. |
| reg<br>    Copy to clipboard | 메모리 할당의 고정된 영역을 나타내는 옵션 속성으로, 이 속성이 없으면 메모리는 무작위 주소에서 동적으로 할당됩니다. |

Last Published: Jan 01, 2026

[Previous Topic
remoteprocessor(remoteproc) 서브시스템 구성](https://docs.qualcomm.com/bundle/publicresource/80-70020-3KO/topics/remoteproc-overview.md) [Next Topic
스케줄러 구성](https://docs.qualcomm.com/bundle/publicresource/80-70020-3KO/topics/scheduler.md)