什么是 udlfb?

这是 DisplayLink USB 2.0 时代图形芯片的驱动程序。

DisplayLink 芯片提供简单的 hline/blit 操作和一些压缩,并将其与 USB 线另一端的硬件帧缓冲区 (16MB) 配对。该硬件帧缓冲区能够驱动 VGA、DVI 或 HDMI 监视器,无需 CPU 干预,直到像素发生变化。

CPU 或其他本地资源执行所有渲染;可以选择将结果与远程硬件帧缓冲区的本地阴影进行比较,以识别已更改的最小像素集;并通过 USB 批量传输逐行压缩和发送这些像素。

由于批量传输的效率以及顶部不需要任何确认的协议,因此效果是非常低的延迟,可以支持非常高的分辨率,并在非游戏和非视频应用程序中具有良好的性能。

模式设置、EDID 读取等是其他批量或控制传输。 模式设置非常灵活 - 能够从任何时序设置几乎任意模式。

通用 USB 图形的优势

  • 能够为任何支持 USB 2.0 的系统添加几乎任意数量的显示器。 在 Linux 上,显示器数量受 fbdev 接口限制(FB_MAX 目前为 32)。 当然,同一主机控制器上的所有 USB 设备共享相同的 480Mbs USB 2.0 接口。

使用内核帧缓冲区接口支持 DisplayLink 芯片的优势

  • DisplayLink 芯片的实际硬件功能几乎与 fbdev 接口一一对应,使得驱动程序相对于其提供的功能而言非常小巧紧凑。

  • X 服务器和其他应用程序可以使用用户模式下的标准 fbdev 接口与设备通信,而无需了解任何关于 USB 或 DisplayLink 协议的信息。 “displaylink” X 驱动程序和略作修改的“fbdev”X 驱动程序都已在其中。

缺点

  • Fbdev 的 mmap 接口假设映射了真实的硬件帧缓冲区。 对于 USB 图形,它只是一个分配的(虚拟)缓冲区。 写入需要被 CPU 检测并编码为 USB 批量传输。 准确的损坏/更改区域通知可以解决此问题。 未来,希望 fbdev 能够增强一个小型的标准接口,以允许 mmap 客户端报告损坏,从而使虚拟或远程帧缓冲区受益。

  • Fbdev 不能很好地仲裁客户端对帧缓冲区的拥有权。

  • Fbcon 假设它找到的第一个帧缓冲区应该被控制台占用。

  • 鉴于 KMS/DRM 的兴起,目前尚不清楚 fbdev 的未来是什么。

如何使用它?

Udlfb 作为模块加载时,将匹配所有 USB 2.0 代 DisplayLink 芯片(Alex 和 Ollie 系列)。 然后它将尝试读取监视器的 EDID,并在 DisplayLink 设备和监视器的功能之间设置最佳通用模式。

如果 DisplayLink 设备成功,它将绘制一个“绿屏”,这意味着从硬件和 fbdev 软件的角度来看,一切都很好。

此时,将存在一个 /dev/fb? 接口,供用户模式应用程序打开并使用标准 fbdev 调用开始写入 DisplayLink 设备的帧缓冲区。 请注意,如果使用 mmap(),默认情况下,用户模式应用程序必须发送损坏通知才能触发已更改区域的重绘。 或者,可以重新编译 udlfb 并启用实验性 defio 支持,以支持基于页面错误的检测机制,该机制可以在没有显式通知的情况下工作。

udlfb 最常见的客户端是 xf86-video-displaylink 或修改后的 xf86-video-fbdev X 服务器。 这些服务器没有真正的 DisplayLink 特定代码。 它们写入标准帧缓冲区接口,并依靠 udlfb 来完成其工作。 它们具有的一个额外功能是能够通过 udlfb 的损坏接口(希望将其标准化为所有需要损坏信息的虚拟帧缓冲区)将 X DAMAGE 协议扩展中的矩形报告给 udlfb。 这些损坏通知允许 udlfb 有效地处理已更改的像素。

模块选项

通常不需要 udlfb 的特殊配置。 但是,有一些选项。

从命令行,将选项传递给 modprobe

modprobe udlfb fb_defio=0 console=1 shadow=1

或者通过编辑 /sys/module/udlfb/parameters/PARAMETER_NAME 动态更改选项

cd /sys/module/udlfb/parameters
ls # to see a list of parameter names
sudo nano PARAMETER_NAME
# change the parameter in place, and save the file.

拔下/重新插入 USB 设备以应用新设置。

或者要永久应用选项,请创建一个 modprobe 配置文件,例如带有文本的 /etc/modprobe.d/udlfb.conf

options udlfb fb_defio=0 console=1 shadow=1

接受的布尔选项

fb_defio

使用 fb_defio (CONFIG_FB_DEFERRED_IO) 内核模块通过页面错误跟踪帧缓冲区的已更改区域。 使用 mmap 但不报告损坏的标准 fbdev 应用程序应该能够启用此功能。 当与支持通过 ioctl 报告已更改区域的 X 服务器一起运行时禁用,因为此方法更简单、更稳定且性能更高。 默认值:fb_defio=1

控制台

允许 fbcon 连接到 udlfb 提供的帧缓冲区。 如果 fbcon 和其他客户端(例如带有 --shared-vt 的 X)发生冲突,则可以禁用。 默认值:console=1

阴影

分配第二个帧缓冲区来阴影当前通过 USB 总线在设备内存中的内容。 如果任何像素未更改,则不传输。 花费主机内存以节省 USB 传输。 默认启用。 仅在极低内存系统上禁用。 默认值:shadow=1

Sysfs 属性

Udlfb 在 /sys/class/graphics/fb? 中创建多个文件,其中 ? 是特定 DisplayLink 设备的连续帧缓冲区 ID

edid

如果将有效的 EDID blob 写入此文件(通常通过 udev 规则),则 udlfb 将使用此 EDID 作为备份,以防读取连接到 DisplayLink 设备的监视器的实际 EDID 失败。 这对于无法通过 EDID 传达其功能的固定面板等特别有用。 读取此文件将返回连接的监视器的当前 EDID(或最后写入的备份值)。 这对于获取连接的监视器的 EDID 非常有用,可以将其传递给诸如 parse-edid 之类的实用程序。

metrics_bytes_rendered

呈现的像素字节的 32 位计数

metrics_bytes_identical

基于阴影帧缓冲区检查,发现有多少字节未更改的 32 位计数

metrics_bytes_sent

通过 USB 传输以将生成的已更改像素传达给硬件的字节的 32 位计数。 包括压缩和协议开销

metrics_cpu_kcycles_used

处理上述像素使用的 CPU 周期(以千个周期为单位)的 32 位计数。

metrics_reset

仅写。 写入此文件的任何内容都会将上述所有指标重置为零。 请注意,上面的 32 位计数器会非常快速地翻转。 要获得可靠的结果,请设计性能测试以在非常短的时间内(一分钟或更短时间是安全的)开始和结束。

Bernie Thompson <bernie@plugable.com>