精华内容
下载资源
问答
  • Linux DRM 理解

    2021-02-20 16:01:10
    Linux 显示子系统结构框架 向上提供标准API给到应用使用 管理GPU和Display模块 相较于原来的framebuffer结构,DRM将更多的硬件模块抽象并管理起来,所以更加的灵活方便; 包含如下模块: GEM(Graphics ...

    1. DRM 概念介绍

    DRM 是Direct Render Manager的缩写:

    • Linux 显示子系统结构框架
      • 向上提供标准API给到应用使用
      • 管理GPU和Display模块
    • 相较于原来的framebuffer结构,DRM将更多的硬件模块抽象并管理起来,所以更加的灵活方便;

    包含如下模块:

    • GEM(Graphics Execution Manager) 用于管理显示buffer的申请和释放
      • DUMB:只支持连续的物理内存,基于Linux底层的CMA内存管理实现,多用于小分辨率的场景
      • PRIME:可以支持连续 & 非连续内存,基于DMA-BU机制,可以实现buffer共享,多用于大内存复杂场景
      • FENCE:buffer同步机制,基于dma_fence实现,解决buffer控制不同步而出现的撕裂、抖帧、回帧等现象
    • KMS (Kernel Mode Sstting)用于设置显示相关配置,显示画面
      • 硬件模块划分
        • CRTC:配置timing、resolution等参数
        • ENCODER:将data数据转换为输出数据格式的模块
        • Connector:连接器,显示数据传输模块,比如LVDS TX / MIPI DSI / HDMI
        • Panels:物理屏幕,同时也包含硬件模块中Overlay的图层;
      • 其他相关概念
        • framebuffer:显示buffer中的数据,一般是GPU渲染的数据或者camera输入数据;
        • VBLANK:DRM框架中显示同步信号,以DPU中vsync信号触发;
        • page flip:当前framebuffer中数据填充已经完成,可以送显信号;
        • property:drm框架中的通用配置项,用于补充上述无法包含的内容信息‘

    image-20210220151427205

    如图所示,相较于原始FB结构,DRM device结构,将相关的硬件模块都抽象出来对象进行管理,则可以更加灵活的配置

    2. 对比HW结构分析

    这里是一个显示模块的大体框架结构:

    image-20210220153917106

    上图仅描述数据path(控制部分未添加):

    • DPU从framebuffer中读取数据
    • 经控制合成缩放等处理后输出给到LVDS Encoder模块
    • Encoder 模块将数据转换为物理线路信号发送到PHY上输出;

    可以看到数据输出path为:DPU – LVDS – TX,与DRM中抽象概念可以一一对应起来:

    • CRTC 对应DPU
    • Encoder 对应 LVDS Encoder
    • Connector对应PHY或者线路,不涉及过多控制,可以在code中不用特别体现

    image-20210220152138258

    详细来看DPU的内部结构:

    • Display Engine中包含我们之前叙述的Overlay模块,以及后边的合成模块;
    • Output Engine中配置Display timing相关配置;
    • 支持旋转、缩放、PQ等处理;

    此部分硬件支持功能可以灵活地在DRM中添加控制;

    3. code分析

    首先来看维基百科上的DRM Architecture图示:

    image-20210220155002517

    • 实现libdrm库,用于在user层提供标准API来操作 DRM device ,并获取其中的各个组件(CRTC、Connector、Encoder)
    • 实现kernel层中core管理:
      • 对接上层libdrm结构
      • 提供注册接口,实际实现drv时通过此类接口注册crtc、encoder、connector等
      • 对应物理设备操作的ioctl也与实际drv进行链接
    • kernel中的GEM管理
    展开全文
  • 好久没有写过博客了,工作之后平时都没有总结,感觉像做了学到很多...好了,言归正传,来介绍下我最近一年都在做的东西,Linux DRM 显示驱动。刚开始收到任务准备接手 DRM 工作的时候,直接先看下代码路径,[~/gi...

    好久没有写过博客了,工作之后平时都没有总结,感觉像做了学到很多东西,但是又感觉什么都没有学到,似懂非懂(真尼玛纠结)。突然别人说的一句话,学东西不仅仅是自己学会就好了,要尝试把你知道的讲给别人听,然而在讲诉的过程中,自己就会清楚自己到底懂还是不懂。好了,言归正传,来介绍下我最近一年都在做的东西,Linux DRM 显示驱动。

    刚开始收到任务准备接手 DRM 工作的时候,直接先看下代码路径,

    [~/github_projs/linux] (analogix_dp_upstream) 817h40m $ ls drivers/gpu/drm/

    amd drm_edid.c drm_panel.c msm

    armada drm_edid_load.c drm_pci.c nouveau

    ast drm_encoder_slave.c drm_plane_helper.c omapdrm

    ati_pcigart.c drm_fb_cma_helper.c drm_platform.c panel

    atmel-hlcdc drm_fb_helper.c drm_prime.c qxl

    bochs drm_flip_work.c drm_probe_helper.c r128

    bridge drm_fops.c drm_rect.c radeon

    cirrus drm_gem.c drm_scatter.c rcar-du

    drm_agpsupport.c drm_gem_cma_helper.c drm_sysfs.c rockchip

    drm_atomic.c drm_global.c drm_trace.h savage

    drm_atomic_helper.c drm_hashtab.c drm_trace_points.c shmobile

    drm_auth.c drm_info.c drm_vma_manager.c sis

    drm_bridge.c drm_internal.h drm_vm.c sti

    drm_bufs.c drm_ioc32.c exynos tdfx

    drm_cache.c drm_ioctl.c fsl-dcu tegra

    drm_context.c drm_irq.c gma500 tilcdc

    drm_crtc.c drm_legacy.h i2c ttm

    drm_crtc_helper.c drm_lock.c i810 udl

    drm_crtc_internal.h drm_memory.c i915 vgem

    drm_debugfs.c drm_mipi_dsi.c imx via

    drm_dma.c drm_mm.c Kconfig virtio

    drm_dp_helper.c drm_modes.c Makefile vmwgfx

    drm_dp_mst_topology.c drm_modeset_lock.c mga

    drm_drv.c drm_of.c mgag200

    好特么高端,直接就放在了 “gpu/” 路径下。GPU 这东西一直很神秘,说说当时我心里飘过的关键字:"高逼格"、"ARM Mali"、"代码不开源"。心里一顿暗爽,这么高端的东西肯定很好玩。老习惯先百度几篇中文的资料来看看,结果一搜,出来的全特么是什么 "数字版权保护" 的叽叽。不开森啊、不开森  :/  难道是这个东西太新了,git log 一看,提交时间也是 2008 年啊,看来只能说当时关键字匹配不好。

    commit c0e09200dc0813972442e550a5905a132768e56c

    Author: Dave Airlie Date: Thu May 29 10:09:59 2008 +1000

    drm: reorganise drm tree to be more future proof.

    With the coming of kernel based modesetting and the memory manager stuff,

    the everything in one directory approach was getting very ugly and

    starting to be unmanageable.

    This restructures the drm along the lines of other kernel components.

    It creates a drivers/gpu/drm directory and moves the hw drivers into

    subdirectores. It moves the includes into an include/drm, and

    sets up the unifdef for the userspace headers we should be exporting.

    Signed-off-by: Dave Airlie

    当时也不会,所以就硬着头皮,直接以 HDMI 开始,代码里面加 LOG 来看看这是个什么鬼。换在现在,我就不用这种方法来坑大家了(不然写这个博客,也就太没意思了)。首先 WIKI 搜下 "Linux DRM",出来的内容不错,原文贴出来:

    The Direct Rendering Manager (DRM) is a subsystem of the Linux kernel responsible for

    interfacing with GPUs of modern video cards. DRM exposes an API that user space programs

    can use to send commands and data to the GPU, and perform operations such as configuring

    the mode setting of the display. DRM was first developed as the kernel space component of

    the X Server's Direct Rendering Infrastructure,[1] but since then it has been used by other

    graphic stack alternatives such as Wayland.

    WIKI 里面概括的还是比较清楚的,如上面英文所诉,DRM 由两个部分组成:一是 Kernel 的子系统,这个子系统对硬件 GPU 操作进行了一层框架封装。二是提供了一个 libdrm 库,里面封装了一系列 API,用来进行图像显示。整体看来和在 Android 上用的 Direct Frame Buffer 差不多嘛,Android Kernel 走的是 FB 的框架,然后 Android HAL 层那边抽象出了一个 FBDEV,用来进行 FB IOCTRL 的统一管理。然而 DRM 就相当于对图形设备进行集中处理,并且多出了个漂亮的 libdrm 库。都说没图说个 JB,来来贴两张 WIKI 上面的对比图片 (左边是 Without DRM,右边是 With DRM,点击图片可以看大图)

    ea4cae9aacee915332749356f7c5e7e2.png

    Without DRM

    5f0b9378c6ac1d4f59e6984c0a796f23.png

    With DRM

    DRM allows multiple programs concurrently access to the 3D video card avoiding collisions

    现在应该知道 DRM 大概的流程是什么样子了,那继续看看我当时真正需要开发的部分:

    [~/github_projs/linux] (analogix_dp_upstream) 817h21m $ ls drivers/gpu/drm/rockchip/

    analogix_dp-rockchip.c rockchip_drm_drv.h rockchip_drm_gem.c

    dw_hdmi-rockchip.c rockchip_drm_fb.c rockchip_drm_gem.h

    Kconfig rockchip_drm_fbdev.c rockchip_drm_vop.c

    Makefile rockchip_drm_fbdev.h rockchip_drm_vop.h

    rockchip_drm_drv.c rockchip_drm_fb.h

    乍眼一看,跟 GPU 没毛线关系(有点伤心),看起来更像是显示接口的开发(但是也挺有意思的)。其中的 VOP(Video Output Processor) 又指 SoC 的 LCDC 模块,主要可以完成图层渲染、色彩信号转换(YUV - > RGB)、LCDC Timing 输出,而 HDMI / eDP 则具体的显示接口。而 GEM / FBDEV 我猜是和硬件 IOMMU 内存管理相关的东西,drm_drv 则应该是 Rockchip Drm Platform 和 DRM 大框架对接的部分。

    好勒,今天介绍的差不多了,以后有机会再具体介绍下具体 DRM 具体的显卡驱动怎么写,以及问问神秘的 GPU 小组,看看 DRM 和 GPU 有没有配合起来。

    Thanks,

    - Yakir

    展开全文
  • 1. 关于linux DRM的介绍以及基本的single buff, duble buff的使用,请参考这里面的介绍比较详尽。2. plane操作这里以atmel SAMA5D27 的LCD控制器为例,LCD有4个planes,base plane, over1 plane, over2 plane, HEO ...

    1. 关于linux DRM的介绍以及基本的single buff, duble buff的使用,请参考

    这里面的介绍比较详尽。

    2. plane操作

    这里以atmel SAMA5D27 的LCD控制器为例,LCD有4个planes,

    base plane, over1 plane, over2 plane, HEO plane

    先介绍下drmModeSetPlane,该函数用来设定plane的位置、长宽参数:

    drmModeSetPlane(plane_id, crtc_id, fb_id, 0,

    crtc_x, crtc_y, crtc_w, crtc_h,

    src_x<<16, src_y<<16, src_w << 16, src_h << 16);

    比如:

    drmModeSetPlane(plane_id, crtc_id, fb_id, 0,

    10,20, 200, 200,

    0<<16, 0<<16, 200<< 16, 200<< 16);

    表示在屏幕(10,20)坐标处设定size为200x200的plane

    3. property

    每个plane有很多的属性,如旋转、透明度等,这些属性可以通过drmModeGetProperty和drmModeObjectSetProperty来进行获取和设定

    关于多层plane及相关property的操作代码,参考:

    4. modetest使用

    modetest是libdrm下的一个很有用的drm测试程序,使用示例如下:

    $modetest -M atmel-hlcdc -s 24@31:800x480

    24是connect id, 31 crtc id,这些id可以使用$./modetest  命令来获取

    执行命令后

    800x480的屏幕上会显示彩条

    $modetest -M atmel-hlcdc -s 24@31:800x480 -w 30:alpha:100 -P 30@31:200x200+200+200

    在base plane上显示id为30的plane,位置为(200,200),大小为200x200,同时设定该plane的透明度为100(最大255),这里的-w是设定property 参数

    展开全文
  • 转自:  ...   根据自己的理解来转述一下: ...DRMlinux 下的图形渲染架构(Direct Render Manager) , 具体的说是显卡驱动的一种架构(驱动如何玩? 把功能封装成 open/close/ioctl 等标准接口,应用程序调用...

    转自: 

    http://manpages.ubuntu.com/manpages/utopic/man7/drm-kms.7.html

     

    根据自己的理解来转述一下:

     

    摘要:

    DRM 是linux 下的图形渲染架构(Direct Render Manager) ,  具体的说是显卡驱动的一种架构(驱动如何玩? 把功能封装成 open/close/ioctl 等标准接口,应用程序调用这些接口来驱动设备)。

    作为显卡,最基本的功能就是把用户的绘图输出到显示屏上,DRM 如何去实现呢,先看看DRM 把“这件事”给你概括的几个基本要素:

    画布(FrameBuffer) ,  绘图现场(CRTC) , 输出转换器(Encoder) ,  连接器(Connector)  ,  然后就到显示屏了

     

    1  画布( FrameBuffer )

    对计算机来说,FrameBuffer 就是一块驱动和应用层都能访问的内存,当然画图之前要有一定的格式化,比方说我可以规定什么样的色彩模式(RGB24 , I420 , YUUV 等等), 分辨率是多大,还有啥参数,那就要到绘图现场去看了 :p

    2  绘图现场(CRTC)  

    简写翻译过来是阴级摄像管上下文,在DRM 里 CRTC 就表示显示输出的上下文了,首先 CRTC 内指一个 FrameBuffer 地址, 外连一个Encoder。 它们俩之间如何沟通? 这就是显示模式(ModeSet)要做的事情,ModeSet 包括了像前面提到的色彩模式 , 还有说显示的时序(timings , ModeLines 等都代表了这个意西)等, 通常时序可以按以下来表达 

    PCLK HFP HBP HSW X_RES VFP VBP VSW Y_RES

    像素时钟 水平前回扫 水平后回扫 水平同步头 水平有效长度 垂直前回扫 垂直后回扫 垂直同步头 垂直有效长度

     

    一个CRTC 可以连接多个 Encoder , 干啥用,实现复制屏幕功能。

     

    3  输出转换器(Encoder )

    想想 CRT 这种土疙瘩就够复杂了,我们的显卡很牛奔的可以连接各种不同的设备,显然输出需要不同的信号转换器,将内存的像素转换成显示器需要的信号(DVID , VGA , YPbPr , CVBS 等等……)

     

    4 连接器 (Connector )

    不是指物理线,回到DRM 这是一个抽象的数据结构 ,代表连接的显示设备,从这里我们可以得到设备的EDID , DPMS 连接状态等.

     

    5 显示面(Planner) 

    咦,怎么多出来一个。我也很呐闷,以上的东东不够地干活? 其实很多创新往往源于人对现实界的不满足。你又要看文字学习,又要看电影打游戏, 还有厉害的可以一边聊天一边看电影。 这里对立出来两个概念,像文字交互这种小范围更新的Graphics 模式,和全幅更新速度奇快的 Video 模式,这两种模式将显卡的使用拉上了两个极端。

    于是 Planner 的概念就发挥了很好的作用,它给视频刷新提供了一条绿色通道,偶不和图形搞在一起了,偶是一个新的图层(或overlay),可以叠加在Graphic之上或之下,偶还可以缩放…

    文档上说 Planner 也在 FrameBuffer 上,这个没关系,这里我们看出来 CRTC 里要显示的东东应该是一种组合(blending)了。 

     

     

    看懂了概念,下一篇来分析具体的数据结构和接口。

     

     

    参考文档:

    http://manpages.ubuntu.com/manpages/utopic/man7/drm-kms.7.html

    http://events.linuxfoundation.org/sites/events/files/lcjpcojp13_pinchart.pdf

    http://landley.net/kdocs/htmldocs/drm.html

    http://events.linuxfoundation.org/sites/events/files/slides/brezillon-drm-kms.pdf

    http://elinux.org/images/7/71/Elce11_dae.pdf

    一 上一篇介绍了 linux 的显示驱动drm 的架构,在这里按一定顺序回顾一下:

    1 我把显示器连到显卡的DVI输出口, 这个连接抽象成 Connector

     2    在 DVI 的 Connector 上驱动会分配 DVI 信号的 Encoder ,  如果没分配, connector 资源上会找到 所有可用的 encoders

     3    encoder 是为图像扫描现场 crtc 服务的, 驱动可能会给encoder 分配crtc , 或者从 encoder 的 possible_crtc 上能找到可用的

     4    crtc 扫描现场要配置显示图像的物理内存区 fb

     5    fb -> crtc -> encoder - > connector 这种关系绑定之后,绘图工作已经开始, 你可以在fb 上任意写画,然后立马得到显示!

    6 然而为了避免图像撕裂,可以建立多 fb (缓冲) 通过 pageFlip 操作来刷新画图。

    7 当然还有专为video 刷新用的plane , plane 也要绑定到 crtc  才能工作。

    二 总结 + drm api 的使用:

    api 使用参考 David Herrmann <dh.herrmann@googlemail.com> 的 drm-howto 以及 weston 还有 drm自带的 modetest 程序


    drm api 核心配置就是要绑定一个 crtc 的关系 fb -> crtc -> encoder - > connector  

    我们来看“一”的回顾,咋是按照逆向的顺序?哈哈其实这样才顺理成章, api 如何用,往下看:

    1 首先要打开drm 驱动模块,然后获取所有的资源

    fd = open("/dev/dri/card0", O_RDWR | O_CLOEXEC);

    drmModeRes res = drmModeGetResources(fd);    

    res 里有啥, res 里告诉了有几个connector , 几个 encoder , 几个 crtc 等以及他们的id , 完全不成套!

    2 从 connector 开始, 顺藤摸瓜

    先获取 connecotr 的具体资源

    drmModeConnector *  conn = drmModeGetConnector(fd, res->connectors[i]);

    conn资源里重要的有两部分,一部分是通过线缆读出来显示器的 "modes " 如 1920x1080@60 等, 当然你要选一个最喜欢的

    另一部分是encoder 按照一章节的2顺序开始找 encoder (看 drmModeConnector 的定义)  :p

    3 给encoder 寻找合适的 crtc

    按照一章节的 3 顺序找 crtc

    4 为 crtc 创建fb

     drm 的例子 modetest 写的很详细,  ARGB  可以直接 drmModeAddFB , 多平面的fb 可以用 drmModeAddFB2

    5 绑定

    核心四元组 < fb , crtc , conn ,  mode >


      int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId,

                   uint32_t x, uint32_t y, uint32_t *connectors, int count,

                 drmModeModeInfoPtr mode);


    6 pageFlip

      extern int drmModePageFlip(int fd, uint32_t crtc_id, uint32_t fb_id,
                     uint32_t flags, void *user_data);    

     这个的玩法得好好记下,

    首先 poll (drm_fd ) 可以收到 drm 的 POLLIN  消息, 消息里面无非两种一种是 VBLANK , 一种是 pageFlip complete

    其次 收到 消息后必须要 调用drmHandleEvent(drm_fd , &evctx); 来处理消息 ,记得必须把你的 pageFlip 处理函数填到evctx里,

    pageFlip 处理函数里干啥呢, pageFlip 一帧结束了,当然要 pageFlip 下一帧!


         7 plane

    plane 的玩法没搞明白,尝试了下,使用多缓冲 调 drmModeSetPlane 来换页可以实现视频的播放,但遇到两个问题:

    其一是 SetPlane 的时机, 如何等待一个显示器的场同步? 看了 vblank 的code 感觉 vblank 是针对一个显卡的同步,但我有多个显示器呢?

    其二是SetPlane 的运行耗时,我的 i3 cpu 执行一次用了 22 ~ 23 ms , 莫名其妙。

    本想着plane 的yuv 通道可以节省资源,有这两大问题在就没法办了, pageFlip 的 fb 只能跟显示器相同颜色空间,并且通常是 ARGB !!


    ---------------------
    作者:walletiger
    来源:CSDN
    原文:https://blog.csdn.net/walletiger/article/details/46596399

    linux ModeSetting学习

    2014年04月13日 20:35:24 Libresoft 阅读数:3725 标签: linux kernel mode setting drm

    1、数据及数据结构:

    Connector:代表显卡上的插口,有几个Connector表示会有几个输出。

    CRTC:crt controller,负责将帧缓存中的数据传送到Connector,数据在传送到Connector之前会经过Encoder。 帧缓存 --> CRTC --> Encoder --> Connector --> 显示器。

    FrameBuffer:在这里帧缓存并不是指的显存上的某一块区域,而是Linux DRM抽象出来的一个概念,用fb_id表示。 

    drm_mode_create_dumb:drmIoctl的参数,意思是请求内核创建缓存。 这个才是真正的内存块,可以使用mmap映射到程序虚拟内存中。Framebuffer的创建中必须指定一个缓存的id。

     

    2、函数:

    drmModeSetCrtc:最核心的函数之一,它负责将建立从帧缓存到Connector的关联。只有调用它,显示器才能显示缓存中的数据。

    drmModePageFlip:直译就是翻页,笔者的理解是 drm_mode_create_dumb类型的缓存其实是双缓存,只有调用此函数之后,crtc才能将之前写入的数据传送给显示器。

     

    3、代码:

    找到处于连接状态的Connector

     

     
    1. drmModeConnector* FindConnector(int fd)

    2. {

    3. drmModeRes *resources = drmModeGetResources(fd); //drmModeRes描述了计算机所有的显卡信息:connector,encoder,crtc,modes等。

    4. if (!resources)

    5. {

    6. return NULL;

    7. }

    8.  
    9. drmModeConnector* conn = NULL;

    10. int i = 0;

    11. for (i = 0; i < resources->count_connectors; i++)

    12. {

    13. conn = drmModeGetConnector(fd, resources->connectors[i]);

    14. if (conn != NULL)

    15. {

    16. //找到处于连接状态的Connector。

    17. if (conn->connection == DRM_MODE_CONNECTED && conn->count_modes > 0 && conn == NULL)

    18. {

    19. break;

    20. }

    21. else

    22. {

    23. drmModeFreeConnector(conn);

    24. }

    25. }

    26. }

    27.  
    28. drmModeFreeResources(resources);

    29. return conn;

    30. }

     

     

    查找与Connector匹配的Crtc

     

     
    1. int FindCrtc(int fd, drmModeConnector *conn)

    2. {

    3. drmModeRes *resources = drmModeGetResources(fd);

    4. if (!resources)

    5. {

    6. fprintf(stderr, "drmModeGetResources failed\n");

    7. return -1;

    8. }

    9.  
    10. unsigned int i, j;

    11.  
    12. for (i = 0; i < conn->count_encoders; ++i)

    13. {

    14. drmModeEncoder *enc = drmModeGetEncoder(fd, conn->encoders[i]);

    15. if (NULL != enc)

    16. {

    17. for (j = 0; j < resources->count_crtcs; ++j)

    18. {

    19. // connector下连接若干encoder,每个encoder支持若干crtc,possible_crtcs的某一位为1代表相应次序(不是id哦)的crtc可用。

    20. if ((enc->possible_crtcs & (1 << j)))

    21. {

    22. int id = resources->crtcs[j];

    23. drmModeFreeEncoder(enc);

    24. drmModeFreeResources(resources);

    25. return id;

    26. }

    27. }

    28.  
    29. drmModeFreeEncoder(enc);

    30. }

    31. }

    32.  
    33. drmModeFreeResources(resources);

    34. return -1;

    35. }

     

     

     

    绘制一张全色的图:

     

     
    1. void SetColor(unsigned char *dest, int stride, int w, int h)

    2. {

    3. struct color {

    4. unsigned r, g, b;

    5. };

    6.  
    7. struct color ccs[] = {

    8. { 255, 0, 0 },

    9. { 0, 255, 0 },

    10. { 0, 0, 255 },

    11. { 255, 255, 0 },

    12. { 0, 255, 255 },

    13. { 255, 0, 255 }

    14. };

    15.  
    16. static int i = 0;

    17.  
    18. unsigned int j, k, off;

    19. unsigned int r = 255;

    20. unsigned int g = 1;

    21. unsigned int b = 1;

    22.  
    23. for (j = 0; j < h; ++j)

    24. {

    25. for (k = 0; k < w; ++k)

    26. {

    27. off = stride * j + k * 4;

    28. *(uint32_t*)&(dest[off]) = (ccs[i].r << 16) | (ccs[i].g << 8) | ccs[i].b;

    29. }

    30. }

    31.  
    32. i++;

    33.  
    34. printf("draw picture\n");

    35. }

     

     

    主函数:

     

     
    1. #define _FILE_OFFSET_BITS 64

    2. #include <inttypes.h>

    3. #include <stdio.h>

    4. #include <stdlib.h>

    5. #include <sys/mman.h>

    6. #include <xf86drm.h>

    7. #include <xf86drmMode.h>

    8. #include <fcntl.h>

    9. #include <unistd.h>

    10. #include <string.h>

    11. int main(int argc, char *argv[])

    12. {

    13. int ret, fd;

    14. fd = open("/dev/dri/card0", O_RDWR | O_CLOEXEC | O_NONBLOCK);

    15. if (fd < 0)

    16. {

    17. /* Probably permissions error */

    18. fprintf(stderr, "couldn't open %s, skipping\n", "");

    19. return -1;

    20. }

    21.  
    22. drmSetMaster(fd);

    23.  
    24. drmModeConnectorPtr connector = FindConnector(fd);

    25. int width = connector->modes[0].hdisplay;

    26. int height = connector->modes[0].vdisplay;

    27.  
    28. printf("display is %d*%d.\n", width, height);

    29.  
    30. int crtcid = FindCrtc(fd, connector);

    31.  
    32. struct drm_mode_create_dumb creq;

    33. memset(&creq, 0, sizeof(creq));

    34.  
    35. creq.width = width;

    36. creq.height = height;

    37. creq.bpp = 32;

    38. creq.flags = 0;

    39.  
    40. ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &creq);

    41. if (ret)

    42. {

    43. printf("create dumb failed!\n");

    44. }

    45.  
    46. uint32_t framebuffer = -1;

    47. uint32_t stride = creq.pitch;

    48.  
    49. //使用缓存的handel创建一个FB,返回fb的id:framebuffer。

    50. ret = drmModeAddFB(fd, width, height, 24, 32, creq.pitch, creq.handle, &framebuffer);

    51.  
    52. if (ret)

    53. {

    54. printf("failed to create fb\n");

    55. return -1;

    56. }

    57.  
    58.  
    59. struct drm_mode_map_dumb mreq; //请求映射缓存到内存。

    60. mreq.handle = creq.handle;

    61.  
    62. ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &mreq);

    63. if (ret)

    64. {

    65. printf("map dumb failed!\n");

    66. }

    67.  
    68. // 猜测:创建的缓存位于显存上,在使用之前先使用drm_mode_map_dumb将其映射到内存空间。

    69. // 但是映射后缓存位于内核内存空间,还需要一次mmap才能被程序使用。

    70. unsigned char* buf = mmap(0, creq.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, mreq.offset);

    71. if (buf == MAP_FAILED)

    72. {

    73. printf("mmap failed!\n");

    74. }

    75.  
    76. memset(buf, 255, creq.size);

    77.  
    78. //一切准备完毕,只差连接在一起了!

    79. ret = drmModeSetCrtc(fd, crtcid, framebuffer, 0, 0, &connector->connector_id, 1, connector->modes);

    80.  
    81. if (ret)

    82. {

    83. fprintf(stderr, "failed to set mode: %m\n");

    84. return -1;

    85. }

    86.  
    87. int cc = 0;

    88. while (cc < 5)

    89. {

    90. SetColor(buf, stride, width, height);

    91. drmModePageFlip(fd, crtcid, framebuffer, DRM_MODE_PAGE_FLIP_EVENT, 0);

    92. cc++;

    93. sleep(2);

    94. }

    95.  
    96. printf("over\n");

    97. getchar();

    98. close(fd);

    99. exit(0);

    100. return ret;

    101. }

    展开全文
  • linux drm框架

    千次阅读 2017-03-10 13:33:56
    转自:  http://manpages.ubuntu.com/manpages/utopic/man7/drm-kms.7.html ...DRMLinux 下的图形渲染架构(Direct Render Manager) , 具体的说是显卡驱动的一种架构(驱动如何玩? 把功能封装成 open/close/io
  • linux drm 架构

    2020-12-28 10:00:11
    DRMlinux 下的图形渲染架构(Direct Render Manager) , 具体的说是显卡驱动的一种架构(驱动如何玩? 把功能封装成 open/close/ioctl 等标准接口,应用程序调用这些接口来驱动设备)。 作为显卡,最基本的功能...
  • Linux内核FL2000DX / IT66121FN软件狗DRM驱动程序 完全重新实现了FrescoLogic FL2000DX DRM驱动程序和ITE Tech IT66121F驱动程序,从而允许基于Linux中此类芯片的启用完整的显示控制器功能。 建筑司机 签出代码并...
  • Linux DRM kernel

    千次阅读 2018-01-15 14:05:46
    Whoops,上次写完《Linux DRM Graphic 显示简单介绍》博文后,心情还是蛮愉悦的,来来,这次在说说具体的显卡驱动。  1. DRM 框架分解 DRM 框架提供了一系列的 IOCTL 行为,但是绝大部分可以分成两类行为...
  • Linux DRM how-to 例子

    2019-01-05 14:00:04
    基本上DRM架构全部取代了传统的fb模式, Linux Graphic DRM subsystem 的测试历程,主要是基于libdrm库进行图形的操作,
  • Linux GPU+DRM调试文档

    2020-04-19 08:34:09
    嵌入式Linux平台GPU+DRM驱动调试文档,欢迎大家下载
  • linux drm 架构 基础

    千次阅读 2019-05-29 09:59:50
    DRM,英文全称Digital Rights Management, 可以翻译为:数字版权管理 由于数字化信息的特点决定了必须有另一种独特的技术,来加强保护这些数字化的音视频节目内容,文档、电子书籍的版权,该技术就是数字权限管理...
  • linux drm kms libdrm

    2020-04-17 14:58:31
    http://dvdhrm.wordpress.com/2012/12/21/advanced-drm-mode-setting-api/...http://dvdhrm.wordpress.com/2012/09/13/linux-drm-mode-setting-api/ http://moi.vonos.net/linux/drm-and-kms/ https://blog.csdn...
  • 简述 Linux DRM 架构

    千次阅读 2019-04-17 20:16:22
    这里写自定义目录标题PurposeOverviewArchitectureComponentsFramebuffera. Information stored Purpose Overview 我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的...DRM stands for Direct Renderi...
  • Linux DRM KMS 驱动简介

    万次阅读 多人点赞 2015-09-23 22:13:38
    Whoops,上次写完《Linux DRM Graphic 显示简单介绍》博文后,心情还是蛮愉悦的,来来,这次在说说具体的显卡驱动。 DRM 框架分解DRM 框架提供了一系列的 IOCTL 行为,但是绝大部分可以分成两类行为:Graphics ...
  • Linux驱动开发之DRM驱动

    千次阅读 2019-08-05 19:16:52
    参考 DRM 驱动程序开发(开篇) drm 驱动是如何创建 fb device 的 Linux中的DRM 介绍 Linux Graphic DRI 显示子系统 介绍1 Xilinx DRM KMS driver
  • Linux DRM(二) --Xorg/DRM

    千次阅读 2020-11-22 22:12:22
      The Direct Rendering Manager (DRM) is a subsystem of the Linux kernel responsible for interfacing with GPUs of modern video cards. DRM exposes an API that user-space programs can use to send ...
  • Linux DRM(二)基本概念和特性

    万次阅读 多人点赞 2017-10-30 16:29:42
    在《Linux DRM (一) Display Server》我们了解了 DRM 诞生的历史缘由。 本篇我们朝着 DRM 本尊再走几步,先介绍几个 DRM 的基本概念和特性,最后简单介绍 RK DRM 依赖的 Component 框架。
  • LInux DRM Developer Guide

    千次阅读 2018-01-15 13:59:32
    http://www.landley.net/kdocs/htmldocs/drm.html#idp5066496 ...Linux DRM Developer's Guide Jesse Barnes Initial version  Intel Corporation  jesse.barnes@intel.com>   Lauren
  • Linux DRM(三) -- DRM KMS/ Debug

    千次阅读 2020-11-23 07:11:16
    这个函数是通过module(drm_core_init)明确在系统启动时进行调用,指定设备的major号,linux中默认为226。创建并初始化一个idr机制,这个机制其实原理上就是一个哈希表,由内核系统维护,能够快速的查找。 调用...
  • Linux中的DRM

    千次阅读 2016-06-14 09:59:57
    如果在搜索引擎离搜索 DRM 映入眼帘的尽是Digital Rights Managemen,也就是数字版权加密保护技术。这当然不是我们想要的解释。在类unix世界中还有一个DRM即The Direct Rendering Manager,它是DRI(Direct Rendering...
  • linux drm原理及应用

    千次阅读 2020-03-29 22:56:42
    linux drm()设计之初是作为一套display数据传输流程,用于将camera采集的视频数据抛给display显示。 drm驱动与应用程序之间封装了一个中间层libdrm,应用程序可以通过调用libdrm提供的接口实现对drm驱动的操作,相对...
  • 这个文档是准对INTEL平台的linux内核中有关Display相关的文档。INTEL使用DRM的显卡驱动框架来管理视频输出。文档对DRM代码框架作出了详细解释。
  • 不知道大家是否还记得,之前我有引用 Wiki 中对 DRM 的介绍,这里我们再回顾一下:DRM 由两个部分组成:一是 Kernel 的子系统,这个子系统对硬件 GPU 操作进行了一层框架封装。二是提供了一个 libdrm 库,里面封装了...
  • imx8 Linux DRM modetest

    千次阅读 2019-10-10 10:32:06
    Linux DRM modetest And Qt DRM Test https://github.com/grate-driver/libdrm/tree/master/tests root@imx8qmmek:/etc# modetest --help usage: modetest [-cDdefMPpsCvw] Query options: -c list ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,563
精华内容 3,025
关键字:

drmlinux

linux 订阅