就我而言,我像这样分配内存:
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);