驱动程序必须通过在DRM设备上调用drm_mode_config_init()来初始化模式设置核心。该函数初始化结构drm_device的mode_config字段,并且永远不会失败。完成后,必须通过初始化以下字段来设置模式配置。
- int min_width min_height;int max_width max_height;帧缓冲区的最小和最大宽度和高度(以像素为单位)。
- struct drm_mode_config_funcs *funcs;模式设置函数。
概述
KMS提供给用户空间的基本对象结构相当简单。帧缓冲区(由结构drm_framebuffer表示,参见帧缓冲区抽象)提供给平面。平面由结构drm_plane表示,更多细节请参见平面的抽象。一个或多个(甚至没有)平面将它们的像素数据输入到一个CRTC(由结构drm_crtc表示,参见CRTC抽象)中进行混合。精确的混合步骤在平面组成属性和相关章节中有更详细的解释。
对于输出路由,第一步是编码器(由drm_encoder结构表示,参见Encoder抽象)。这些实际上只是用于实现KMS驱动程序的助手库的内部构件。除了让用户空间不必要地更复杂地判断CRTC和连接器之间的哪些连接是可能的,以及支持哪种克隆,它们在用户空间API中没有任何用途。不幸的是,编码器已经暴露在用户空间,因此不能删除他们。此外,暴露出来的限制常常是驱动错误设置的,在许多情况下,并没有强大到足以表达真正的限制。一个CRTC可以连接到多个编码器,对于一个活动的CRTC,必须至少有一个编码器。
显示链中的最终端点是连接器(由结构drm_connector表示,请参阅连接器抽象)。连接器可能有不同的编码器,但是内核驱动程序为每个连接器选择使用哪个编码器。例如DVI,它可以在模拟和数字编码器之间切换。编码器还可以驱动多个不同的连接器。每个活动编码器都有一个活动连接器。
在内部,输出管道更复杂一些,与今天的硬件更加匹配:
在内部,两个额外的helper对象开始发挥作用。首先,为了能够共享编码器的代码(有时在同一个SoC上,有时在芯片外),一个或多个桥(由结构drm_bridge表示)可以链接到一个编码器。这个链接是静态的,不能更改,这意味着交叉栏(如果有的话)需要在CRTC和任何编码器之间映射。通常对于有桥接的驱动程序来说,编码器级别的代码已经没有了。原子驱动程序可以省略所有的编码器回调,本质上只留下一个虚拟的路由对象,这是向后兼容所需要的,因为编码器是公开给用户空间的。
第二个对象用于面板,由结构drm_panel表示,请参阅面板助手参考。面板没有固定的绑定点,但是通常链接到嵌入drm_connector结构的驱动程序私有结构。
请注意,目前桥接连接和以及连接器和面板的交互仍在不断变化,并没有真正完全理清。