// open /dev/ion
static int ion_fd_get(void)
{
static int fd = -1;
if (fd == -1) {
fd = ion_open();
}
return fd;
}
/*
* @brief alloc ion buffer
* @param ion_fd ion_user_handle_t
* @param size ion buffer size
* @param addr user_space addr
*/
static int alloc_ion_buffer(int *ion_fd, int size, void **addr)
{
int ret;
if (!ion_fd || !addr || size < 0) {
printf("%s: Invalid argument!\n", __FUNCTION__);
return -1;
}
ret = ion_alloc_fd(ion_fd_get(), size, 4096, 1 << 25, 1, ion_fd);
if (ret < 0) {
printf("%s: ion allocate failed!\n", __FUNCTION__);
return -1;
}
*addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, *ion_fd, 0);
if (*addr == MAP_FAILED) {
printf("%s: mmap failed!\n", __FUNCTION__);
return -1;
}
return 0;
}
用户空间API
用户空间API通过ioctl直接与驱动交互。
// in .//src/system/core/libion/include/ion/ion.h
int ion_open();
int ion_close(int fd);
int ion_alloc(int fd, size_t len, size_t align, unsigned int heap_mask,
unsigned int flags, ion_user_handle_t *handle);
int ion_alloc_fd(int fd, size_t len, size_t align, unsigned int heap_mask,
unsigned int flags, int *handle_fd);
int ion_sync_fd(int fd, int handle_fd);
int ion_free(int fd, ion_user_handle_t handle);
int ion_map(int fd, ion_user_handle_t handle, size_t length, int prot,
int flags, off_t offset, unsigned char **ptr, int *map_fd);
int ion_share(int fd, ion_user_handle_t handle, int *share_fd);
int ion_import(int fd, int share_fd, ion_user_handle_t *handle);
// in ./src/system/core/libion/kernel-headers/linux/ion.h
/**
* struct ion_fd_data - metadata passed to/from userspace for a handle/fd pair
* @handle: a handle
* @fd: a file descriptor representing that handle
*
* For ION_IOC_SHARE or ION_IOC_MAP userspace populates the handle field with
* the handle returned from ion alloc, and the kernel returns the file
* descriptor to share or map in the fd field. For ION_IOC_IMPORT, userspace
* provides the file descriptor and the kernel returns the handle.
*/
struct ion_fd_data {
ion_user_handle_t handle;
int fd;
}