日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

fb驱动安装linux系统,drm 驱动是如何创建 fb device 的

發(fā)布時(shí)間:2025/3/20 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 fb驱动安装linux系统,drm 驱动是如何创建 fb device 的 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

drm 驅(qū)動(dòng)是如何創(chuàng)建 fb device 的

什么是 drm?

drm 是一個(gè) Linux 內(nèi)核的顯示系統(tǒng)驅(qū)動(dòng)框架,區(qū)別于另外一個(gè) DRM數(shù)字版權(quán)保護(hù)

drm 是一個(gè)管理 GPU 的顯示框架

在內(nèi)核級(jí)別提供內(nèi)存管理,中斷處理, DMA控

為應(yīng)用程序提供統(tǒng)一的操作接口

如何使用 drm 接口

libdrm

fb device

libdrm

內(nèi)核提供的 IOCTRL 太多,libdrm 用于簡(jiǎn)化編程管理當(dāng)前的顯示器,并修改當(dāng)前的模式成為 KMS (drm-kms - Kernel Mode-Setting)

借助 libdrm 的強(qiáng)大 API 接口,如果內(nèi)核支持 PRIME API ,也可以使用 PRIME 接口實(shí)現(xiàn)更為靈活的內(nèi)存操作。

fb device

drm 驅(qū)動(dòng)可以模擬一個(gè) fb device, 默認(rèn)是 default CRTC, 更多關(guān)于 fb device ,可以參考 內(nèi)核 framebuffer 文檔, fb device 是大多數(shù) Linux 系統(tǒng)顯示的基礎(chǔ)。

The X Server, Linux 桌面系統(tǒng)的顯示服務(wù)

Android gralloc, 安卓系統(tǒng)顯示 HAL

本文討論的問題是 drm 驅(qū)動(dòng)是如何虛擬 drm crts 為 fb device

文章基于內(nèi)核版本 linux-3.18

VERSION = 3

PATCHLEVEL = 18

SUBLEVEL = 0

EXTRAVERSION = -linux4sam_5.0-alpha7

NAME = Diseased Newt

drm 的代碼位于:

drivers/gpu/drm/

1. 設(shè)備驅(qū)動(dòng)創(chuàng)建 fbdev

drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c: dc->fbdev = drm_fbdev_cma_init(dev, 24,

drivers/gpu/drm/sti/sti_drm_drv.c: drm_fbdev_cma_init(dev, 32,

drivers/gpu/drm/tilcdc/tilcdc_drv.c: priv->fbdev = drm_fbdev_cma_init(dev, bpp,

drivers/gpu/drm/rcar-du/rcar_du_kms.c: fbdev = drm_fbdev_cma_init(dev, 32, dev->mode_config.num_crtc,

調(diào)用的是 drm_fbdev_cma_init

struct drm_fbdev_cma *drm_fbdev_cma_init(struct drm_device *dev,

unsigned int preferred_bpp, unsigned int num_crtc,

unsigned int max_conn_count)

{

struct drm_fbdev_cma *fbdev_cma;

struct drm_fb_helper *helper;

int ret;

fbdev_cma = kzalloc(sizeof(*fbdev_cma), GFP_KERNEL);

...

helper = &fbdev_cma->fb_helper;

drm_fb_helper_prepare(dev, helper, &drm_fb_cma_helper_funcs);

...

ret = drm_fb_helper_initial_config(helper, preferred_bpp);

if (ret < 0) {

dev_err(dev->dev, "Failed to set initial hw configuration.\n");

goto err_drm_fb_helper_fini;

}

return fbdev_cma;

其中最重要的數(shù)據(jù)結(jié)構(gòu)是 drm_fb_helper_funcs

static const struct drm_fb_helper_funcs drm_fb_cma_helper_funcs = {

.fb_probe = drm_fbdev_cma_create,

};

2. 完成 fb 設(shè)備的創(chuàng)建:

static int drm_fbdev_cma_create(struct drm_fb_helper *helper,

struct drm_fb_helper_surface_size *sizes)

{

struct drm_fbdev_cma *fbdev_cma = to_fbdev_cma(helper);

struct drm_mode_fb_cmd2 mode_cmd = { 0 };

struct drm_device *dev = helper->dev;

struct drm_gem_cma_object *obj;

struct drm_framebuffer *fb;

unsigned int bytes_per_pixel;

unsigned long offset;

struct fb_info *fbi;

size_t size;

int ret;

DRM_DEBUG_KMS("surface width(%d), height(%d) and bpp(%d)\n",

sizes->surface_width, sizes->surface_height,

sizes->surface_bpp);

bytes_per_pixel = DIV_ROUND_UP(sizes->surface_bpp, 8);

mode_cmd.width = sizes->surface_width;

mode_cmd.height = sizes->surface_height;

mode_cmd.pitches[0] = sizes->surface_width * bytes_per_pixel;

mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,

sizes->surface_depth);

size = mode_cmd.pitches[0] * mode_cmd.height;

obj = drm_gem_cma_create(dev, size);

if (IS_ERR(obj))

return -ENOMEM;

fbi = framebuffer_alloc(0, dev->dev);

if (!fbi) {

dev_err(dev->dev, "Failed to allocate framebuffer info.\n");

ret = -ENOMEM;

goto err_drm_gem_cma_free_object;

}

fbdev_cma->fb = drm_fb_cma_alloc(dev, &mode_cmd, &obj, 1);

if (IS_ERR(fbdev_cma->fb)) {

dev_err(dev->dev, "Failed to allocate DRM framebuffer.\n");

ret = PTR_ERR(fbdev_cma->fb);

goto err_framebuffer_release;

}

fb = &fbdev_cma->fb->fb;

helper->fb = fb;

helper->fbdev = fbi;

fbi->par = helper;

fbi->flags = FBINFO_FLAG_DEFAULT;

fbi->fbops = &drm_fbdev_cma_ops;

ret = fb_alloc_cmap(&fbi->cmap, 256, 0);

if (ret) {

dev_err(dev->dev, "Failed to allocate color map.\n");

goto err_drm_fb_cma_destroy;

}

drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth);

drm_fb_helper_fill_var(fbi, helper, fb->width, fb->height);

offset = fbi->var.xoffset * bytes_per_pixel;

offset += fbi->var.yoffset * fb->pitches[0];

dev->mode_config.fb_base = (resource_size_t)obj->paddr;

fbi->screen_base = obj->vaddr + offset;

fbi->fix.smem_start = (unsigned long)(obj->paddr + offset);

fbi->screen_size = size;

fbi->fix.smem_len = size;

return 0;

err_drm_fb_cma_destroy:

drm_framebuffer_unregister_private(fb);

drm_fb_cma_destroy(fb);

err_framebuffer_release:

framebuffer_release(fbi);

err_drm_gem_cma_free_object:

drm_gem_cma_free_object(&obj->base);

return ret;

}

流程圖

Created with Rapha?l 2.1.0 drm_fbdev_cma_init drm_fb_helper_initial_config drm_fb_helper_single_fb_probe register_framebuffer

總結(jié)

以上是生活随笔為你收集整理的fb驱动安装linux系统,drm 驱动是如何创建 fb device 的的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。