Hi, I've a galaxy Nexus which has a camera that seems to be tied to the OMX system which itself uses tiler and ion. I'm trying to make the camera work under Replicant(A 100% free android distribution (http://replicant.us/) ). So the free software userspace camera libs do some read/write operations on the device node of the OMX driver. At some point write fails(during camera preview) and the following messages appear in dmesg:
<6>[ 111.117462] PVR_K:(Error): GetHandleStructure: Handle index out of range (1835561824 >= 0) [454, /home/gnutoo/embedded/android/replicant-4.0/kernel/samsung/tuna/drivers/gpu/pvr/handle.c] <6>[ 111.117584] PVR_K:(Error): PVRSRVLookupHandle: Error looking up handle (149) [1407, /home/gnutoo/embedded/android/replicant-4.0/kernel/samsung/tuna/drivers/gpu/pvr/handle.c] <6>[ 111.117706] PVR_K:(Error): PVRSRVExportFDToIONHandle: Failed to look up MEM_INFO handle [78, /home/gnutoo/embedded/android/replicant-4.0/kernel/samsung/tuna/drivers/gpu/pvr/ion.c] which is because: * the OMX kernel driver (drivers/rpmsg/rpmsg_omx.c at https://gitorious.org/replicant/kernel_samsung_tuna/blobs/replicant-4.0/drivers/rpmsg/rpmsg_omx.c ) uses PVRSRVExportFDToIONHandle. * I don't have installed and can't use the proprietary powervr libraries. So I've to replace PVRSRVExportFDToIONHandle... So I tried 2 approaches: Approach 1) ----------- in userspace I've done a very simple program that opens /dev/pvrsrvkm and loops after it(in order to prevent the .close()) it didn't result in the full initialization but the range changed from (1835561824 >= 0) to (1835561824 >= 256) There is a program in android named pvrsrvinit and tracing it gives somehthing like that: open("/dev/pvrsrvkm", O_RDWR) = 3 fcntl64(3, F_SETFD, FD_CLOEXEC) = 0 ioctl(3, 0xc01c670c, 0xbeff698c) = 0 getpid() = 5094 ioctl(3, 0xc01c6745, 0xbeff69cc) = 0 I must find to what theses ioctl correspond and find their arguments. I've also found an exploit that might help in understanding how things works: http://jon.oberheide.org/files/levitator.c The problem is that I don't understand the pvr driver pass-trough since it's too much messy. I also wonder if it can be called source code because the GPLv2 says: "The source code for a work means the preferred form of the work for making modifications to it.", and it seems that they stripped the comments. Approach 2) ----------- The approach 2 was to modify the OMX driver in order to make it not use PVRSRVExportFDToIONHandle. More precisely to replace that line: handle = PVRSRVExportFDToIONHandle(fd, &pvr_ion_client); I failed at that too, however it seem easier than understanding the ioctls of the pass-trough powervr driver by reading it. So far I've done that: +struct ion_handle *global_handle; +struct ion_client *global_pvr_ion_client; static int rpmsg_omx_open(struct inode *inode, struct file *filp) { [...] + ion_phys_addr_t phys; + size_t size; + struct tiler_view_t view; + void * memory; + int ret; + struct omap_ion_tiler_alloc_data sAllocData = { + /* TILER will align width to 128-bytes */ + /* however, SGX must have full page width */ + .w = 900, //ALIGN(psLINFBInfo->var.xres, PAGE_SIZE / ( 4 /*psLINFBInfo->var.bits_per + .h = 1600, /* psLINFBInfo->var.yres, */ + .fmt = TILER_PIXEL_FMT_32BIT, //psLINFBInfo->var.bits_per_pixel == 16 ? TILER_PIXEL_F + .flags = 0, + }; [...] + global_pvr_ion_client = ion_client_create(omap_ion_device, + 1 << ION_HEAP_TYPE_CARVEOUT |1 << OMAP_ION_HEAP_TYPE_TILER, "pvr"); + ret = omap_ion_tiler_alloc(global_pvr_ion_client, &sAllocData); + global_handle = sAllocData.handle; + if (ret < 0 ) + printk("[DBG] %s normal alloc failed \n",__func__); + else + printk("[DBG] %s normal alloc succedded \n",__func__); //it succeed + ion_phys(global_pvr_ion_client, sAllocData.handle, &phys, &size); + tilview_create(&view, phys, 900, 1600); And then instead of calling PVRSRVExportFDToIONHandle I would do that: [...] +fd = buffer; +file = fget(fd); +if (file){ + handle = global_handle; + if (handle && + !ion_phys(global_pvr_ion_client,handle, &paddr, &unused)) { } [...] However that fails too: AT some point file is false(like when the pvr libs are in use) and pa becomes 0 in pa = (phys_addr_t) tiler_virt2phys(buffer); which makes the whole thing fail. So I wonder how to make it work: maybe someone knows enough how the powervr driver works or how ion is supposed to work and what I am doing wrong... Denis. -- unsubscribe: [email protected] website: http://groups.google.com/group/android-kernel
