framebuffer注册源码解读

注册的源码解读

framebuffer主要是填充fb_info然后调用register_framebuffer()函数

获取到注册fb的锁之后,开始调用do_register_framebuffer

do_register_framebuffer

第一段

1622行,检查显示控制器的大小端配置是否与当前CPU的大小端兼容,如果不兼容,有没有转换支持

1625行,系统早期U-boot会提供一个极简缓冲区用来显示临时画面,当真的显卡驱动加载时,二者的显存物理地址会冲突,所以将之前旧的移除掉

1631-1643行,给当前fb找个合理的次设备号,同时增加系统中注册进去的fb数量

创建一个fb_class的类设备,并且带上主次设备号

device_create会在内核中创建对应的device实体,同时还会让devtmpfs创建/dev下的设备inode节点

对于/dev下fb对应的inode字符节点的统一file_operations,则是由fbmem_init进行创建的

它通过register_chrdev这个函数为一个主设备号(FB_MAJOR)下的0-255次设备号都映射到同一个file_operations,即fb_fops

同时创建fb_class为名为graphics的类

之后,fb的设备就会被注册为graphics类设备,同时由deftmpfs负责去/dev下创建对应的inode节点,到file_operations的映射由VFS(虚拟文件系统)通过主次设备号进行映射

第二段

这里的pixmap是给内核在屏幕上画图用的中转缓冲区,比如开机企鹅logo,还有fbcon在屏幕上输出控制台字符用的

如果当前显卡驱动没分配这块缓冲区,则这里按照默认配置分配一份

1664则是设置位图掩码,表示支持1到32像素宽高的字体

第三段

1670行,创建一个双向链表,用来保存当前屏幕支持的所有显示模式(分辨率、刷新率、时序等,即 struct fb_videomode)

1673行,控制休眠时需不需要切换图形界面到文本终端

1678,1679,这个地方实际上就是把可变参数固定下来,写到modelist中

因为可变参数在frame_buffer注册过程中,可能会因为一些原因被修改,所以最后这里固定下来(真正支持的参数),挂到modelist上

1680行,registered_fb[i]中的下标i对应着次设备号,这里就很方便让file_operations从这个全局数组拿到当前的fb_info结构体了

1683行,因为接下来马上要通知控制台子系统(fbcon)来接管这块新屏幕作为终端输出,而控制台子系统在内核中是由全局的console_lock保护的,所以这里获得该lock

1685行,对当前的fb_info也加锁,防止在广播注册事件的瞬间,被其他线程修改

1691行,**向所有调用过fb_register_client()的内核模块广播,**一个新的fb_info已经注册好了

  • 最核心的订阅者是 fbcon(Framebuffer Console) :当 fbcon 收到 FB_EVENT_FB_REGISTERED 事件后,它的回调函数 fbcon_fb_registered() 会立刻被触发,将该 fb_info 与虚拟终端(/dev/tty1 等)绑定,紧接着你就能在物理屏幕上看到开机企鹅 Logo 了
  • 这个通知机制实际上是调用挂在该事件上的所有函数
    如果要让该fb打印出控制台信息,还需要修改启动参数,将控制台输出重定向到该tty,一般是tty1

fb_fops

这里和v4l2需要维持复杂的vb2_buffer和v4l2_buffer之间的转换来从内核态与用户态之间转换数据不同

往fb写数据的位置 本质上是写一块DDR中分配的给显卡读的(即显存)专用的内存区域

在不开启垂直同步的情况下,直接往里写数据,显卡负责自己按照配置好的刷新率从这个DDR分配的内存区域读取数据

这种读取数据的方式不是DMA,而是由于显示控制器本来就是一个总线设备,其能自己通过总线读取总线地址上的数据

所以它还是需要参与总线仲裁与竞争

总线地址是SOC设计的时候就规划好的,DDR只是挂在其中的一块区域

显示控制器通过总线地址访问的时候实际上走的是DDR控制器

当给出一段总线地址比如 0x8000_0000 + 0x1234

bash 复制代码
总线地址:  0x8000_1234
            │
            ├─ 高位 [31:28] = 0x8  → 解码出"这是 DDR 窗口"
            ├─ 中位           → 行地址 (row)
            └─ 低位           → 列地址 (column) + bank
相关推荐
2401_862880821 小时前
嵌入式Linux系统移植与驱动开发完整指南
linux·c语言·驱动开发
坤坤子吖1 小时前
Linux 线程同步与互斥——互斥锁
linux·服务器·c++·笔记·学习
TDTC_XQ1 小时前
Linux网络编程accept的讲解
linux·服务器·c++
Python自动化直播2 小时前
自动化笔记:素材管理、命名、轮换的几条土办法
linux·运维·数据库
FlightYe2 小时前
音视频修炼之容器与协议(一):MP4和MOV的box剖析
android·linux·c++·ffmpeg·音视频
暴雨课堂2 小时前
tp5 tp6被攻击篡改后恢复
linux·服务器·php
djjjx.3 小时前
Linux进程篇(四):内核托底与生死交错 ,深度硬核剖析“僵尸”与“孤儿”进程
linux·运维·服务器
为思念酝酿的痛3 小时前
Reactor反应堆模式
linux·服务器·网络
沫璃染墨3 小时前
从零入门计算机网络系列(六):TCP套接字编程实战——从listen监听到客户端与服务器通信
linux·服务器·c++·tcp/ip·计算机网络·tcp