1. 概述
本篇文章对嵌入式领域使用的显示系统做一个介绍,主要关注显示硬件组成和2D显示驱动。
2. 名词解释
2.1 显卡
显卡顾名思义最基础的功能就是显示,在上世纪80年代,显卡还不像今天显卡这样有丰富的功能,它的最主要的功能就是输出显示图像,比如下图的VGA显卡。
这时候的显卡能输出的分辨率比较低,一般都是640x480、800x600等。
2.2 2D加速卡
随着像windows这样的操作系统的发展,单纯的使用显卡的基础显示功能已经不能满足日常的需求了,比如你将一个窗口从左边移动到右边,这个操作过程窗口本身的内容没有任何改变,只是位置变化了,如果完全使用cpu去绘制的话就需要不停的改变窗口新位置对应的显存中的数据,这样会导致cpu占用率很高,一直在执行绘图任务没法去执行其他任务。
这时2D加速的需求就出现了,也就是在显卡上添加一个2D加速的功能,比如上述的窗口移动操作,有了2D加速之后,程序员们只需要告诉2D加速硬件窗口原始的位置、新的位置还有窗口代表的图像大小信息,2D加速硬件就会自动将原位置图像更新到新位置显存处,由于这一过程cpu仅在最开始设置2D加速硬件的时候参与到,后续的更新过程完全不需要参与,所以cpu这时就可以去执行别的任务。这个搬运的过程其实本质上就是一个DMA传输的过程,在2D加速中这个术语叫bitblt,当然2D加速还有很多其他的功能,比如画直线、矩形单色填充、颜色混合等等。
像windows这样的操作系统会将基础的2D图形绘制封装出一些列的接口,这些接口底层如果有2D加速硬件的话,会使用驱动提供的2D加速功能实现,如果没有的话则使用cpu绘制实现。有2D加速功能的这些显卡则可以称为2D加速卡。
2.3 3D加速卡
随着多媒体时代的到来,人们在PC上玩游戏的需求越来越大,这当中的3D游戏也逐渐发展起来。但是人们很快发现单纯的使用cpu去渲染图形已经满足不了复杂的3D游戏需求,这时候3D加速卡应运而生。使用3D加速卡可以让专用的硬件去渲染生成图形内容而cpu就可以腾出手来干点别的事情,比如播放音频等等。这个时期3D加速卡和2D加速卡都是单独的计算机外设,后期也有厂商将2D和3D功能集成在一张卡上,比如Voodoo Banshee。
2.4 GPU
虽然3D加速卡可以加速3D图形的渲染,但是在3D图形学渲染流程中的T&L(Transform and Lighting,多边形转换与光源处理)还是由cpu来计算的,这种情况一直持续到英伟达发布GeForce 256。GeForce 256是第一个支持使用专有硬件处理T&L的3D加速卡,英伟达并把这种硬件芯片命名为GPU(Graphics Processing Unit),从此3D图形学中的所有渲染过程都可以由硬件来处理了,cpu只需要配合GPU准备好渲染资源,然后通知GPU使用这些资源渲染图形就行了。
3. 显示系统类型
下面简单介绍下在不同硬件平台下经常碰到的几种显示系统组成情况。
3.1 集显
集显叫做集成显卡,因为是集成在桥片内部的,所以叫集成显卡。在以前x86的架构中,集显是在北桥芯片中的,集显一般将一部分内存当作显存用,一般情况下没有独立显存,但是也不是绝对的,比如龙芯7A1000桥片中的集显就有独立显存。
3.2 核显
核显叫做核芯显卡,是和cpu核一起集成在处理器芯片中的,而不像集显那样是在处理器外部的,当然这种叫法一般都是特指对x86平台上处理器内部的核显,核显一般也是将部分内存当作显存来使用。核显和集显一般都包含了显示控制器DC和图形处理器GPU这两个部件,也就是说同时有显示功能又有3D渲染的功能。
3.3 独显
独显叫做独立显卡,一般通过PCI或者PCIe接口插入到主板上使用,比如英伟达和AMD都有自己的独立显卡。独立显卡一般有自己的独立显存,但是可能并不一定有3D渲染功能,比如SM768显卡只有显示和2D加速功能而没有3D加速功能。
3.4 嵌入式显示
在嵌入式中,显示控制器和GPU一般都是两个独立的外设控制器,可能是不同厂商的IP核。比如我们手机中的arm架构soc,GPU可能是arm mali、power vr等厂商提供的IP核,显示控制器可能是另外的厂商提供。在这种架构中,都是将部分内存拿来当作显存使用,一般出于成本和功耗的考虑不会有独立显存。
4. 不同平台显示系统
4.1 x86平台
现在x86平台的显卡基本都是通过PCIe接入,在早期的架构中在北桥中有集显,比如82915这款北桥芯片,集显通过PCIe和北桥传输数据,北桥通过FSB前端总线和cpu传输数据,如下图所示。
在现在的英特尔处理器芯片中,核显被集成到了处理器内部,通过内部ringbus总线和cpu通信,降低了通信延迟,提高了新能,如下图所示。
当然集显和核显的性能针对基础的电脑使用来说是基本满足的,但是如果是玩大型游戏或者是需要工业图形渲染的话,都需要搭配独立显卡来使用,一般的x86主板上都预留了独立显卡的PCIe插槽。
4.2 龙芯平台
4.2.1 2K1000
2K1000是一款双核SOC,自带GPU和DC,GPU和DC通过内部总线连接cpu,如下图所示。
GPU和DC都可以单独工作,在2K1000平台是将内存当作显存使用的。
4.2.2 3A3000 + 7A1000
3A3000处理器需要配合7A1000桥片来使用,7A1000桥片的作用就是类似于以前x86架构中的南北桥功能。在7A1000中有集显,桥片通过HT总线和处理器通信,如下图所示。
在7A1000中,集显既可以使用内存当作显存使用,也可以使用内部的独立显存。
4.3 飞腾平台
飞腾处理器内部没有GPU和DC,所以需要外接PCIe显卡来使用,比如SM768、JM7200等等。也可以配合飞腾的x100套片来使用显示和GPU功能,如下图所示。
4.4 大部分ARM平台
ARM平台的显示系统和2K1000一样,DC和GPU都是可以分开单独工作的,比如全志R16芯片,如下图所示。
在ARM平台上同样是拿内存当显存来使用的。
5. 显卡驱动
5.1 嵌入式平台驱动
针对嵌入式arm平台或者龙芯平台,显示驱动就是单独驱动SOC中的显示控制器,在SylixOS下就是普通的fb驱动,在Linux下就是drm/kms驱动,输出的接口一般有VGA、LVDS、HDMI等等,分辨率都可以通过设置DC相关寄存器来改变。
5.2 通用显卡驱动(VBE驱动)
针对单独的PCIe形式的显卡,现在基本都满足VBE标准,VBE标准是VESA组织制定的一个显示编程接口标准,主要用于统一在x86实模式下显卡显示一系列编程接口,比如设置分辨率、获取显卡支持的分辨率信息等等。VBE最新的标准是3.0版本,制定于上世纪90年代末期,现代的显卡基本都遵守这个标准,这个标准主要是为x86平台制定的,所以显卡厂商将VBE相关功能代码编译成x86指令烧录在显卡的VBIOS中。
VBE功能一般只能在实模式下使用,为了在x86进入保护模式后也能使用VBE功能,Linux中开发了一个x86模拟器,模拟出x86的实模式环境,这样就可以在保护模式下继续使用VBE功能了。在龙芯的PMON中就是使用同样的原理来使用这些PCIe显卡的,PMON中同样有一个x86模拟器,来执行显卡VBIOS中的x86指令从而来设置显卡显示输出。
由于VBE基本是现代显卡都支持的,所有支持VBE的显示驱动理论上都能驱动显卡基本显示输出,比如Linux下的uvesa驱动,SylixOS下x86平台的显卡驱动同样是VBE驱动,所以一套驱动就能驱动不同厂商的显卡。
5.3 专用显卡驱动
虽然VBE驱动一套驱动吃遍所有显卡,很方便,但是也是有缺点的,比如VBE驱动能设置的显示分辨率只能是显卡厂商固化在VBIOS中的几种分辨率,有的显卡可以设置更高的分辨率,但是在VBE中没有支持。因为在现代的显卡中,支持VBE更多的是为了兼容性考虑,VBE更多的是为了“亮机”功能而存在,如果想使用更多的显卡功能就需要专用显卡驱动,比如SM768专有显卡驱动就可以在多个平台上使用,可以设置多种分辨率。
在Linux下,显卡的显示驱动和GPU驱动一般都是在一块的,叫做drm/kms驱动,一些老的显卡可能还是使用的fbdev框架,新的显卡基本都是用drm框架了。
6. FAQ
6.1龙芯和飞腾平台可以通过VBE驱动使用任意显卡显示吗
龙芯片平台基本可以,飞腾平台根据实测基本不可以。因为VBE功能基本依赖显卡厂商的VBIOS,有的显卡VBIOS需要依赖x86的vga端口来设置显卡显示,龙芯的PCIe控制器可以处理vga端口的访问,但是飞腾的PCIe控制则不行,如果一个显卡的VBE实现不依赖vga端口的话,则在飞腾下有可能能被正常驱动显示。在测试中试了AMD的几款显卡只有一款老式的R600显卡能在飞腾下显示,其他的显卡要么显示异常要么完全不能驱动,所以在飞腾下想使用显卡显示的话,最好使用显卡的专用驱动。
2022年4月13日 14:14 1F
妙啊