Ich habe ein Beispiel für android Ionen Nutzung geschrieben:android ion, ioctl von ION_IOC_IMPORT return <0, errno = 9
Der Vater Prozess ein Rohr erzeugt, öffnet sich dann "/ dev/ion" -Gerät, ioctl von ION_IOC_ALLOC , ioctl von ION_IOC_MAP und mmap, und schließlich habe ich die von ION_IOC_MAP zurückgegebene fd und die Länge an den untergeordneten Prozess per Pipe übergeben.
Der untergeordnete Prozess liest fd und Länge aus der Pipe, und das Lesen ist in Ordnung, aber wenn ich ION_IOC_IMPORT mache, gab dies -1 zurück, und das errno ist 9, perror ist "Bad file descriptor".
Die beiden Prozesse sind Root-Benutzer und Selinux ist zulässig.
Vater Prozess Schlüsselcode:
ion_fd = open("/dev/ion", O_RDONLY);
if (ion_fd < 0) {
ALOGE("Failed to open ion device\n");
return -EIO;
}
alloc_data.len = 0x1000;
alloc_data.align = 0x1000;
alloc_data.heap_id_mask = ION_HEAP(ION_SYSTEM_HEAP_ID);
alloc_data.flags = ION_SECURE;
rc = ioctl(ion_fd, ION_IOC_ALLOC, &alloc_data);
if (rc) {
ALOGE("Failed to allocate uspace ion buffer\n");
goto uimp_alloc_err;
}
fd_data.handle = alloc_data.handle;
rc = ioctl(ion_fd, ION_IOC_MAP, &fd_data);
if (rc < 0) {
ALOGE("unable to ion map buffer\n");
goto uimp_map_err;
}
map_fd = fd_data.fd;
addr = mmap(NULL, alloc_data.len,
PROT_READ | PROT_WRITE,
MAP_SHARED , map_fd, 0);
if (!addr) {
ALOGE("mmap failed\n");
rc = -EIO;
goto uimp_mmap_err;
}
write_pattern((unsigned long)addr, alloc_data.len);
fd_data.handle = alloc_data.handle;
rc = ioctl(ion_fd, ION_IOC_SHARE, &fd_data);
if (rc < 0) {
ALOGE("unable to share ion buffer\n");
goto uimp_share_err;
}
itoa(fd_data.fd, ubuf, sizeof(int) * 8);
if (0 > sock_write(wr_fd, ubuf, sizeof(int) * 8))
goto uimp_sock_err;
itoa(alloc_data.len, ubuf, sizeof(int) * 8);
if (0 > sock_write(wr_fd, ubuf, sizeof(int) * 8))
goto uimp_sock_err;
do {
tpid = wait(&child_status);
} while (tpid != child_pid);
Child Prozess Schlüsselcode:
if (0 > sock_read(fd, cbuf, sizeof(int) * 8))
return -EIO;
fd_data.fd = atoi(cbuf);
/* receive buf length */
if (0 > sock_read(fd, cbuf, sizeof(int) * 8))
return -EIO;
size = atoi(cbuf);
ion_fd = open("/dev/ion", O_RDONLY);
if (ion_fd < 0) {
rc = -EINVAL;
goto child_args_err;
}
rc = ioctl(ion_fd, ION_IOC_IMPORT, &fd_data); // it failed here
if (rc) {
ALOGE("ION_IOC_IMPORT failed %d errno %d\n", rc, errno);
perror("ioctl");
rc = -EIO;
goto child_imp_err;
}
addr = mmap(NULL, size, PROT_READ | PROT_WRITE,
MAP_SHARED, fd_data.fd, 0);
if (!addr) {
perror("mmap");
rc = -EIO;
goto child_mmap_err;
}