私の場合は、次のようにメモリを割り当てます。
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);