IONの事前定義されたヒープ型メモリを割り当てる方法は?

IONの事前定義されたヒープ型メモリを割り当てる方法は?

私の場合は、次のようにメモリを割り当てます。

    struct ion_allocation_data arg_alloc;

    arg_alloc.len = len;
    arg_alloc.heap_mask = heap_mask;
    arg_alloc.flags = flags;
    arg_alloc.fd = 0;

    ret = ioctl(client, ION_IOC_ALLOC_V1, &arg_alloc);

カーネルのソースコードでヒープIDが次のように計算されることがわかりました。

    heap_id = 1 << MAGIC_NUMBER;

MAGIC_NUMBERはヒープIDです(ヒープタイプと同じではありません)。このMAGIC_NUMBERは、Laura Abbottのおかげでカーネルの起動時に計算されます。

SHA 2f87f50b Laura Abbott が 2017 年 4 月 18 日午後 09:27 に提出

ステージング:Android:ion: ヒープ登録/列挙リワーク

現在、イオンヒープ登録モデルは古いボードファイルモデルに基づいています。ボードファイル(デバイスツリー)の置き換えは、Ionが望む作業の良い代替ではありません。実際、Ionは、他のプログラムが使用するメモリを決定できるように、システムで利用可能なメモリを表示しようとします。 Ionが無条件デバイスを作成し、ヒープを空の領域として登録するモデルに切り替えます。現在、システムとCMAヒープのみが新しいモデルに変換されます。誰かが変換方法を知りたい場合は、CarveoutとChunk Heapを変換できます。

署名者: Laura Abbott 署名者: Greg Kroah-Hartman

DMAヒープを使いたいです。このヒープの型は列挙型で定義されます。

    typedef enum
    {
    ION_HEAP_TYPE_SYSTEM,
    ION_HEAP_TYPE_SYSTEM_CONTIG,
    ION_HEAP_TYPE_CARVEOUT,
    ION_HEAP_TYPE_CHUNK,
    ION_HEAP_TYPE_DMA,
    ION_HEAP_TYPE_CUSTOM, /*
    * must be last so device specific heaps always
    * are at the end of this enum
    */
    } ion_heap_type;

今問題があります。ここで、 ION_HEAP_TYPE_DMA 列挙は 4 で、この数値はヒープ ID ではありません。私の場合、そのヒープタイプに対応する右ヒープIDマスクは(1 << 1)です(もう一度ありがとう、Laura)。

したがって、「IONの定義済みヒープタイプのメモリをどのように割り当てますか?別のプラットフォームに同じメモリを割り当てる方法は?」という質問が再び発生します。

答え1

ION用ドライバには、ioctlコマンドの "ION_IOC_HEAP_QUERY"パラメータが含まれており、特定のプラットフォームでアクティブなヒープ(名前、タイプ、IDなど)に関する情報を取得するために使用できます。実装例は以下にあります。協会:

int ion_query_heap_cnt(int fd, int* cnt) {
    int ret;
    struct ion_heap_query query;
    memset(&query, 0, sizeof(query));
    ret = ion_ioctl(fd, ION_IOC_HEAP_QUERY, &query);
    if (ret < 0) return ret;
    *cnt = query.cnt;
    return ret;
}

int ion_query_get_heaps(int fd, int cnt, void* buffers) {
    int ret;
    struct ion_heap_query query = {
        .cnt = cnt, .heaps = (uintptr_t)buffers,
    };
    ret = ion_ioctl(fd, ION_IOC_HEAP_QUERY, &query);
    return ret;
}

このAPIの使用例を探すここ:

static int find_ion_heap_id(int ion_client, char* name)
{
    int i, ret, cnt, heap_id = -1;
    struct ion_heap_data *data;
    ret = ion_query_heap_cnt(ion_client, &cnt);
    if (ret)
    {
        AERR("ion count query failed with %s", strerror(errno));
        return -1;
    }
    data = (struct ion_heap_data *)malloc(cnt * sizeof(*data));
    if (!data)
    {
        AERR("Error allocating data %s\n", strerror(errno));
        return -1;
    }
    ret = ion_query_get_heaps(ion_client, cnt, data);
    if (ret)
    {
        AERR("Error querying heaps from ion %s", strerror(errno));
    }
    else
    {
        for (i = 0; i < cnt; i++) {
            struct ion_heap_data *dat = (struct ion_heap_data *)data;
            if (strcmp(dat[i].name, name) == 0) {
                heap_id = dat[i].heap_id;
                break;
            }
        }
        if (i > cnt)
        {
            AERR("No System Heap Found amongst %d heaps\n", cnt);
            heap_id = -1;
        }
    }
    free(data);
    return heap_id;
}

heap_typeからheap_idを取得するために、次の関数を簡単に書き換えることができます。

heap_idを取得したら、次のものを計算する必要があります。

heap_mask = (1 << heap_id);

関連情報