내 경우에는 다음과 같이 메모리를 할당한다.
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에 제출함 Greg Kroah-Hartman이 2017년 4월 18일 오후 9:43에 제출함 parent eb9751db
스테이징: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);