如何分配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 PM 由 Greg Kroah-Hartman 提交,2017 年 4 月 18 日 09:43 PM 父 eb9751db

登台:android:ion:返工堆注册/枚举

当前的 Ion 堆注册模型是基于过时的 board 文件模型。板文件 (devicetree) 的替代品并不能很好地替代 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,而这个数字并不是heap 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);

相关内容