大佬教程收集整理的这篇文章主要介绍了使用Linux中的“直接渲染管理器”在dumbbuffer上调用mmap在使用C时失败,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试在Rust中创建一个与libdrm等效的东西,它不仅仅是对C库的绑定,而是直接使用系统调用.这不是一项容易的任务,因为那里几乎没有DRM的文档,但我正在关注this example in C以获取从哪里开始的提示.
我现在到了我应该创建一个哑缓冲区并将其映射到内存中的点,@R_423_9447@修改屏幕上显示的每像素像素数.为此,我必须使用mmap,但我得到一个非常奇怪的错误.
这是C中的最小工作代码:
#include <errno.h> #include <fcntl.h> #include <stdint.h> #include <stdio.h> #include <String.h> #include <drm/drm.h> #include <drm/drm_mode.h> #include <sys/ioctl.h> #include <sys/mman.h> int main() { // STEP 1: GET ACCESS TO DRM int fd = open("/dev/dri/card0",O_RDWR | O_CLOEXEC); if (fd < 0) { printf("Error in function open(): %s\n",strerror(errno)); return 1; } // STEP 2: CREATE DUMBBUFFER struct drm_mode_create_dumb dreq; dreq.height = 1080,dreq.width = 1920,dreq.bpp = 32,dreq.flags = 0,dreq.handle = 0,dreq.pitch = 0,dreq.size = 0; int ret = ioctl(fd,DRM_IOCTL_MODE_CREATE_DUMB,&dreq); if (ret == -1) { printf("Call to DRM_IOCTL_MODE_CREATE_DUMB Failed: %s\n",strerror(errno)); return 1; } // STEP 3: ADD FRAMEBUFFER struct drm_mode_fb_cmd creq; creq.fb_id = 0; creq.width = dreq.width; creq.height = dreq.height; creq.pitch = dreq.pitch; creq.bpp = dreq.bpp; creq.depth = 24; creq.handle = dreq.handle; ret = ioctl(fd,DRM_IOCTL_MODE_ADDFB,&creq); if (ret == -1) { printf("Call to DRM_IOCTL_MODE_ADDFB Failed: %s\n",strerror(errno)); return 1; } // STEP 4: PREPARE FOR MAPPING struct drm_mode_map_dumb mreq; mreq.handle = dreq.handle; mreq.pad = 0; mreq.offset = 0; ret = ioctl(fd,DRM_IOCTL_MODE_MAP_DUMB,&mreq); if (ret == -1) { printf("Call to DRM_IOCTL_MODE_MAP_DUMB Failed: %s\n",strerror(errno)); return 1; } // STEP 5: MAPPING PROPER void *R_688_11845@ap = mmap(0,dreq.size,PROT_READ | PROT_WRITE,MAP_SHARED,fd,mreq.offset); if (map == MAP_Failed) { printf("Error in function mmap(): %s\n",strerror(errno)); return 1; } else { printf("Address of mapped data: 0x%x\n",map); } return 0; }
这是Rust中完全相同的代码.当然,我的真实代码中有更多的东西,但这个最小的代码足以得到错误:
#![feature(libC)] extern crate libc; use self::libc::{C_char,c_int,c_ulong,c_void,off_t,size_t}; extern { pub fn ioctl(fd : c_int,request : c_ulong,arg : *mut c_void) -> c_int; } fn errno() -> c_int { unsafe { *libc::__errno_LOCATIOn() } } fn get_c_error() -> String { unsafe { let strerr = libc::strerror(errno()) as *mut u8; let length = libc::strlen(strerr as *const c_char) as usize; let mut String = String::with_capacity(length); for i in 0..length { let car = *strerr.offset(i as isizE) as char; if car == (0 as char) { break; } String.push(car); } String } } #[repr(C)] struct CCreateDumb { height : u32,width : u32,bpp : u32,_flags : u32,handle : u32,pitch : u32,size : u64,} #[repr(C)] struct CFrameBuffer { _fb_id : u32,_width : u32,_height : u32,_pitch : u32,_bpp : u32,_depth : u32,_handle : u32,} #[repr(C)] struct CMapDumb { _handle : u32,_pad : u32,offset : u32,} fn main() { // STEP 1: GET ACCESS TO DRM let pathname = "/dev/dri/card0".to_String(); let fd : c_int = unsafe { libc::open(pathname.as_ptr() as *const c_char,libc::O_RDWR | libc::O_CLOEXEC) }; if fd < 0 { panic!("Error in call of C function open(): {}",get_c_error()); } // STEP 2: CREATE DUMBBUFFER let mut dreq = CCreateDumb { height : 1080,width : 1920,bpp : 32,_flags : 0,handle : 0,pitch : 0,size : 0,}; // NB : 0xc02064b2 = DRM_IOCTL_MODE_CREATE_DUMB let mut ret = unsafe { ioctl(fd,0xc02064b2 as c_ulong,&mut dreq as *mut _ as *mut c_void) }; if ret == -1 { panic!("Call to DRM_IOCTL_MODE_CREATE_DUMB Failed: {}",get_c_error()); } // STEP 3: ADD FRAMEBUFFER let mut creq = CFrameBuffer { _fb_id : 0,_width : dreq.width,_height : dreq.height,_pitch : dreq.pitch,_bpp : dreq.bpp,_depth : 24,_handle : dreq.handle,}; // NB : 0xc01c64ae = DRM_IOCTL_MODE_ADDFB ret = unsafe { ioctl(fd,0xc01c64ae as c_ulong,&mut creq as *mut _ as *mut c_void) }; if ret == -1 { panic!("Call to DRM_IOCTL_MODE_ADDFB Failed: {}",get_c_error()); } // STEP 4: PREPARE FOR MAPPING let mut mreq = CMapDumb { _handle : dreq.handle,_pad : 0,offset : 0,}; // NB : 0xc01064b3 = DRM_IOCTL_MODE_MAP_DUMB ret = unsafe { ioctl(fd,0xc01064b3 as c_ulong,&mut mreq as *mut _ as *mut c_void) }; if ret == -1 { panic!("Call to DRM_IOCTL_MODE_MAP_DUMB Failed: {}",get_c_error()); } // STEP 5: MAPPING PROPER let map = unsafe { libc::mmap( 0 as *mut c_void,dreq.size as size_t,libc::PROT_READ | libc::PROT_WRITE,libc::MAP_SHARED,mreq.offset as off_t ) }; if map == libc::MAP_Failed { panic!("Error in call of C function mmap(): {}",get_c_error()); } else { println!("Address of mapped data: 0x{:p}",map); } }
它编译得很好,但是当我执行它时,我得到了这个错误.
使用extern块直接链接到原始的C mmap函数而不是Rust的crate libc并不会改变任何东西.
我看了this project如何@L_720_5@mmap,并尝试做同样的事情,以确保大小和偏移量是页面对齐的,但它没有改变任何东西,因为它们已经是页面对齐的.
This SO question使用名为std :: os :: Memorymap的stdlib工具,但它不再存在.
以上是大佬教程为你收集整理的使用Linux中的“直接渲染管理器”在dumbbuffer上调用mmap在使用C时失败全部内容,希望文章能够帮你解决使用Linux中的“直接渲染管理器”在dumbbuffer上调用mmap在使用C时失败所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。