ion.c
case ION_IOC_SHARE:
case ION_IOC_MAP:
{
struct ion_handle *handle;
handle = ion_handle_get_by_id(client, data.handle.handle);
if (IS_ERR(handle))
return PTR_ERR(handle);
data.fd.fd = ion_share_dma_buf_fd(client, handle);
Kernel ion driver 에서 ION_IOC_SHARE 와 ION_IOC_MAP 은 동일한 logic 이다.
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)
...
ret = ion_ioctl(fd, ION_IOC_MAP, &data);
...
tmp_ptr = mmap(NULL, length, prot, flags, data.fd, offset);
그런데 Android libion 의 ion_map 은 ION_IOC_MAP 이후 mmap 과정을 추가로 수행한다.
이때 전달받은 length 크기만큼 prot 권한으로 mmap 한다.
int ion_share(int fd, ion_user_handle_t handle, int *share_fd)
...
ret = ion_ioctl(fd, ION_IOC_SHARE, &data);
Android libion 의 ion_share 는 ION_IOC_MAP 과 kernel 내에서 동일한 ION_IOC_SHARE 만 수행하고, mmap 과정이 없다. 단순히 share 만을 위한 목적으로 보인다.
int ion_import(int fd, int share_fd, ion_user_handle_t *handle)
...
ret = ion_ioctl(fd, ION_IOC_IMPORT, &data);
ION_IOC_MAP 혹은 ION_IOC_SHARE 를 통해 확보한 fd 를 통해 ion buffer handle 에 대한 handle id 를 확보한다.
fd 는 task 별로 관리되는 자료구조로서 현재 task 에서만 의미 있는 값이다. 그런데 binder driver 를 통하면 from_proc task 의 fd 에 연결된 file 을 target task 에 연결한다.
/*
* copied from fd_install
*/
static void task_fd_install(
struct binder_proc *proc, unsigned int fd, struct file *file)
{
if (proc->files)
__fd_install(proc->files, fd, file);
}
v4.4 drivers/android/binder.c 기준으로 위와 같이 task_fd_install 부분이 이 기능을 하는 것으로 보인다.
참고 자료