有一段时间,我一直在使用

Linux‘

Direct Rendering Manager,这允许我们进行一些非常低级别的图形管理.这通常在C中完成,在

libdrm的帮助下,或直接使用

DRM headers.

我正在尝试在Rust中创建一个与libdrm等效的东西,它不仅仅是对C库的绑定,而是直接使用系统调用.这不是一项容易的任务,因为那里几乎没有DRM的文档,但我正在关注this example in C以获取从哪里开始的提示.

我现在到了我应该创建一个哑缓冲区并将其映射到内存中的点,所以我可以修改屏幕上显示的每像素像素数.为此,我必须使用mmap,但我得到一个非常奇怪的错误.

这是C中的最小工作代码:

#include

#include

#include

#include

#include

#include

#include

#include

#include

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 *map = 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,

fd,

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);

}

}

它编译得很好,但是当我执行它时,我得到了这个错误.

thread ” panicked at ‘Error in call of C function mmap(): Invalid argument’, memmapping.rs:139

note: Run with RUST_BACKTRACE=1 for a backtrace.

使用extern块直接链接到原始的C mmap函数而不是Rust的crate libc并不会改变任何东西.

我看了this project如何调用mmap,并尝试做同样的事情,以确保大小和偏移量是页面对齐的,但它没有改变任何东西,因为它们已经是页面对齐的.

This SO question使用名为std :: os :: MemoryMap的stdlib工具,但它不再存在.

linux直接渲染管理,使用Linux中的“直接渲染管理器”在dumbbuffer上调用mmap在使用C时失败...相关推荐

  1. Mathtype在word中一些数学符号不能显示[比如符号上的波浪线],只能显示方框时的解决办法

    Mathtype在word中一些数学符号不能显示[比如符号上的波浪线],只能显示方框时的解决办法 解决方法 解决方法 打开C:\WINDOWS\Fonts,若里面有MT Extra(TrueType) ...

  2. c4d渲染测试软件,C4D中阿诺德GPU渲染测试

    软件版本:c4d R23+阿诺德 3.2.0版本: 硬件条件:AMD3900X+32G DDR4 3200内存条+3090显卡+m.2硬盘 工程信息:多边形模型面数28w面左右. image.png ...

  3. react大数据量渲染_UseEffect在React中运行无限渲染(超过最大更新深度)

    我有一个Cart组件,里面有一系列Cards. 每次用户从购物车中删除产品时,我都会从本地存储中删除产品, 并将其从用户界面中删除. import React, { useState, useEffe ...

  4. 如何在 3Dmax 中启用 GPU 渲染?

    3D动画是当今娱乐行业广泛使用的一种艺术形式.3ds Max 是 3D 动画世界中使用最广泛的工具之一.该软件被广泛认为是可用于创建高质量 3D 动画的最佳工具之一,并被许多专业动画师和艺术家使用. ...

  5. Unity中的物体渲染顺序

    big seven 文章目录 前言 一.摄像机渲染 二.划分渲染队列 三.不透明物体的渲染 四.透明物体的渲染 五.UGUI元素的渲染 总结 前言 Unity中物体的渲染顺序 提示:以下是本篇文章正文 ...

  6. OA系统中如何实现合同管理?

    合同是现代经济往来的重要形式,合同管理作为OA办公系统中常见的功能之一,是企业管理的一个重要方面.从销售到采购,从合同的数据.归档处理等,合同应该包括哪些部分?如何做好OA系统中的合同管理?OA系统中 ...

  7. 安卓(android)建立项目时失败,出现Android Manifest.xml file missing几种解决方法?(总结中)

    安卓(android)建立项目时失败,出现Android Manifest.xml file missing几种解决方法?(总结中) 参考文章: (1)安卓(android)建立项目时失败,出现And ...

  8. 【Linux 内核 内存管理】Linux 内核堆内存管理 ① ( 堆内存管理 | 内存描述符 mm_struct 结构体 | mm_struct 结构体中的 start_brk、brk 成员 )

    文章目录 一.堆内存管理 二.内存描述符 mm_struct 结构体 三.mm_struct 结构体中的 start_brk.brk 成员 一.堆内存管理 Linux 操作系统中的 " 堆内 ...

  9. Linux中LVM(逻辑卷管理)的使用

    Linux 中我们使用fdisk命令划分好的分区就不能随意的改变,如果不够用的话不可能说把硬盘上的所有数据拷贝后再重新分区,这样可能会导致数据损坏.而在linux中LVM(逻辑卷管理)就可以实现动态的 ...

最新文章

  1. 如何避免安装SQL2005的COM+错误
  2. php实例之简单的留言板,PHP实例一之简单的留言板
  3. python向数据库中添加参数_第四篇:python操作数据库时的传参问题
  4. 连载:告诉你如何设计一个日访问量千万级别的系统,谈oracle的高级设计和开发(2)...
  5. Ubuntu android 开发配置
  6. 无法将 DBNull.Value 强制转换为类型“System.DateTime”。请使用可空类型
  7. 彻底搞懂 python 中文乱码问题_Python BeautifulSoup中文乱码问题的2种解决方法
  8. 关于visio你必须要知道的一些小技巧
  9. 黑马程序员—文件读取路径及行读取的方式,今晚总算有点小懂
  10. 【渝粤教育】国家开放大学2018年秋季 0248-21T电工电子技术 参考试题
  11. mono webservice问题请教
  12. 安装卸载gitlab
  13. eplan p8详细安装步骤文库_Win10系统安装Eplan Electric P8详细步骤
  14. icem划分网格步骤_ICEM CFD教程-icem网格划分教程
  15. 七万字详解paddle-openVINO【CPU】-从环境配置-模型部署全流程
  16. python3自动化软件发布系统pdf_Python 3自动化软件发布系统 -Django 2实战
  17. React 父组件获取子组件的方法/数据(useRef
  18. 高阶篇:4.2.5)DFMEA建议措施及后续完备
  19. Unity3D怪物基本AI
  20. 分享第三方支付申请流程政策

热门文章

  1. 色情网站的光棍节“福利”:加密式挂马玩转流氓推广
  2. 【岩熹解读】今天“麻花”不开心:只靠个别明星的业绩太难了
  3. 简单利用HUDText插件实现血条和怪物伤害减血效果
  4. 开源下载 | 经典著作《机器学习:概率视角》.pdf
  5. c语言竞赛算法编程题目,[C语言编程接龙竞赛]第一题 设计一个N!的算法
  6. atk301指纹识别模块-stm32-串口实现
  7. springboot集成PageHelper
  8. Jmeter(十三)阶梯式压测
  9. 【简化版蒙板扣图】带你轻松走进OPENCV蒙板扣图的世界
  10. COSMIC的后端学习之路——1.3 海量数据去重的Hash与BloomFilter(布隆过滤器),bitmap(位图)