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에 제출함 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);

관련 정보