Hi everybody, first of all I apologize if this is not the right place for this question but I couldn't find any answer in other places and I think this is a good question about DRI. I also apologize for the length of the question! For a security application I'm developing I need direct access to the framebuffer on the graphic device under X on both linux and freebsd. My goal is to memory map the portion of the graphic device memory where pixel values are stored just before they are read by the monitor. I need to achieve this for a couple of well known architectures that will not change in time (say an ati and an nvidia specific card). This would be the best scenario even if it is not really clear to me if it is really possible at all. I've spent days trying to figure out how to do that and I've seen that DRI2 / DRM is probably what I should use. By now I've found 3 possible solutions (sorry if two of these solutions are not DRI related, but maybe some of you have an answer!). If you are not interested in anything but DRI you should jump to point 3. 1. Use of the kernel fbdev (/dev/fb0). Issues: - 1.a What am I really accessing when reading from /dev/fb0? Is that really the videocard memory or some system memory the kernel allocates and keep updated? - 1.b Capturing /dev/fb0 is not working under X unless fbdev is specified as videodriver for X. And that is really really slow! 2. Use of X API and shm extension. This is what screenshot grabber are usually doing. Basically ask X to get the pixmap of the screen root drawable and retrieve it by using a shared memory. Issues: - This is working fine actually but it is using X. I would like something of more low level (that is more reliable for the security applications). Also I'm not sure of the pipeline involved in this process. I guess it is something like: X gets the backbuffer reading directly from the graphic device and copies it to the shared memory. Or is it possible that X is accessing some buffer in system memory that it keeps updated? (Note that I'm supposing DRI2 and hardware acceleration are active and runinng). 3. Use of DRI2 infrastructure and DRM. This would be my favourite solution since I would have the biggest control over what is happening. I've made some test and I failed but I feel I'm close to the solution...but sadly it is not working! I would really appreciate if you validated this procedure and/or if you suggested any possible mistake I've made. So first, DRM seems to be the key...and more precisely, drmMap function seems to be exactly what I need! int drmMap(int fd, drmHandle handle, drmSize size, drmAddressPtr address) I have fd here (I got it by open("/dev/dri/card0")), I need the handle and the size. After a long search and try this is what I've found that should work for getting this information: - I setup a DRI connection using xcb_dri2_connect() and xcb_dri2_authenticate(). This is working. - I call xcb_dri2_get_buffers(...) passing as input drawable the root window of the screen and XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT as the attachment.This is half working. I receive an answer, width and height are correct but, the count attribute is 0! If I call xcb_dri2_create_drawable() with the same drawable, then the xcb_dri2_get_buffers call returns a good answer, where count is 5! I can't really understand this..why 5?..but then I go on with buffer[0] and - I need to convert the buffer name to an handle to be used for the drmMap call. So I execute this code I've found googling and that makes sense to me: struct drm_gem_open open; int ret; open.name = buffer[0].name; open.handle = 0; open.size = 0; do { ret = ioctl (drmFD, DRM_IOCTL_GEM_OPEN, &open); } while (ret == -1 && errno == EINTR); This code is working with no error and at the end I get open.handle with a (seems) good value. - At the end of this I call drmMap(fd, open.handle, open.size, pointer); but this is returning a negative value :-( So, Is this a correct way of doing things? The key could really be that xcb_dri2_get_buffers() is returning count == 0 when called and I need to call xcb_dri2_create_drawable()...but I think that this is wrong since X should have created that at the beginning of the times! Isn't there any other way of retrieving the name of the root drawable of X? Last question: even If I'll manage to read the buffer memory mapping it...will that memory be the final step before monitor, or there will be some other piece of software moving it around to some other buffer? Sorry for the very long post, but I really thing this could be an instructive thread for a lot of people! Thanks! Daniele
- Prev by Date: Compiling nouveau driver for linux 2.6.32-20 kernel.
- Next by Date: OMAP libDRM page_flip_handler vs vblank_handler
- Previous by thread: Compiling nouveau driver for linux 2.6.32-20 kernel.
- Next by thread: OMAP libDRM page_flip_handler vs vblank_handler
- Index(es):