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


当时也不会翻墙,所以就硬着头皮,直接以 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,点击图片可以看大图)

Access to video card without DRM
Without DRM
Access to video card with DRM
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

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐