# メモリを構成および管理する

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=size_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リージョンは `reserved-memory` ノードで定義され、`shared-dma-pool` 互換タグがCMAリージョンを示しています。

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-3JA/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リージョンを4 MBのアドレスベースとサイズに合わせ、ページの移行をサポートします。移行はページブロックレベルにある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ヒープはQualcomm Linuxディストリビューションでサポートされ、カスタムCMAヒープを割り当てることができます。DMA-BUFヒープを使用する場合、`/dev/dma_heap` ファイルシステムのヒープごとにデバイスファイルが存在します。システムヒープと一般的なCMA予備ヒープの他に、独自にCMAタイプのDMA-BUFヒープを作成できます。

以下は、`/dev/dma_heap/system` でQualcomm Linuxカーネルにより作成された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 | このノードに割り当てられ、phandleを使用してこのノードをデバイスツリーの他のノード内から参照するために使用できるラベルを表します。 |
| reg<br>    Copy to clipboard | プロパティを表します。プロパティはメモリ領域のベースとサイズを定義する64ビット値です。 |
| no-map<br>    Copy to clipboard | この領域が分割されており、カーネルがマッピングをアドレス指定可能範囲から削除する必要があることを表します。 |

注釈

- どの領域も重複しないようにする必要があります。領域のサイズを増やす必要がある場合は、それ以降の他の領域をすべて移動してからデバイスツリーで構成することにより、重複が発生しないようにします。
- カーネルは、カーネルの使用のために定義されるメモリ領域の限度がいずれも1MBであることを想定します。
- 分割された既存の領域は、信頼できるファームウェアにより、カーネルのアクセスから保護されます。これらの領域のサイズを小さくしたり、削除したりすると、外部中断が発生して、カーネルがクラッシュする可能性があります。

**CMA領域を追加する**

CMA領域を **reserved-memory** ノードの `arch/arm64/boot/dts/qcom/<SoC>-<board>-<variant>.dts` ファイルに追加するには、以下の構文を使用します。

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
リモート・プロセッサー（remoteproc）サブシステムを構成する](https://docs.qualcomm.com/bundle/publicresource/80-70020-3JA/topics/remoteproc-overview.md) [Next Topic
スケジューラーを構成する](https://docs.qualcomm.com/bundle/publicresource/80-70020-3JA/topics/scheduler.md)