UEFI开发探索06 – 图形显示01

到了我最喜欢的环节了,图形显示!

我曾经写过不少关于图形显示的博客和论文,特别是在Legacy BIOS以及嵌入式设备中的显示。PC的显示一直都遵循着VESA的标准,在底层的访问还是比较一致。虽然在多年的开发中,也在一些主板上出现过奇怪的现象(一次而已。Award某款主板,设置显示模式的时候,花屏。在调用设置显示模式的函数前,多压几次堆栈,问题又消失了。)。但当年写的核心显示代码,运行了近10年了,也没出现过显示的问题。

这是我曾翻烂过的参考书:

图1 参考书

还有这些…

图2 参考书

以及《最新VESA SVGA图形图像编程秘技》 李军著、《C语言游戏编程从入门到精通》,还有图像格式,主要是BMP、PCX和jpeg。哦,还有一本雷军(没错,我就是当年用过这本书,才成为米粉的)和求伯君的《深入DOS编程》。

写得最扎实的是《IBM PC的原理及应用》以及《PC技术内幕》,想了解底层显示原理的可以参考一下。虽然我觉得这些知识有点过时了,但对理解还是有帮助的。

在Foxdisk的博客中,曾经简略的提到了如何进行底层的显示编程,三个步骤:

1)      设置显示模式(如0x103为 800×600 256色的配置);
2)      设置颜色寄存器;
3)      按照图形显示的原理编写画点、画线、画圆等基本函数。

详细的显示原理以及编程没有去讨论,后面会陆续在Foxdisk的系列博客中谈到的。

回到UEFI的显示上,基本的显示原理不会有什么变化,intel也没有重新造一个新的显示模型出来。我觉得UEFI应该还是如上述三个步骤一样执行。无非还是显示模式如何设置,怎么画点,以及如何减少显存换页。查看UEFI spec(对照UEFI spec 2.8),有个关于显示的PROTOCOL,截图如下(uefi spec 2.8 page 448):

图3 EFI_GRAPHICS_OUTPUT_PROTOCOL

开始写代码。

第一个问题就是SetMode。在Spec中提供了两个SetMode函数,一个是EFI_GRAPHICS_OUTPUT_PROTOCOL的,另外一个是EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL的,这让我很困惑。猜测后一个是用来转换Text mode和Graphic mode的。

以前在调试汇编代码时候,int 10h设置显示模式为3,就是进入了Text mode。调试显示程序时,这是常用的代码。因为进入Graphic mode后,debug.exe的信息很多时候是没法显示的,必须回到Text mode才能看到。因此我有上述的猜想。

在调试中,我参照了aptio写的代码,并且对照调试结果,收集了一些信息。未来可能用得上,记录如下。

1.      UGA window模拟环境中,text mode有三种,graphic mode有五种;
2. 以前的代码(aptio)使用了gEfiConsoleControlProtocolGuid来获取protocol,但是在uefi spec2.3.1中已经输出了ConOut了,我以为没有必要再这样使用。怀疑与版本兼容有关,是否EDK1中是这样实现的?
3. GOP在后续版本中替代了UGA。see page 2065 in UEFI_Spec_2_3_1;
4. \EdkCompatibilityPkg\Foundation\Library\Dxe\Graphics,包含了一些使用方法;
5. \EdkCompatibilityPkg\Foundation\Protocol\ConsoleControl,包含了另外一些使用方法;
6. Text mode的第二个模式,columns和rows都是0,怀疑就是EfiConsoleControlScreenGraphics,      转换为graphic mode所要用到的。

照旧将代码放到百度云上了。这次的代码主要是收集信息,加深对UEFI图形显示的理解。将代码编译,显示的信息如下。

图4 代码运行输出

可以看到各种显示信息:Text Mode有三种,Mode 0应该就是我们常用的80×25的字符模式;Graphic则有5种,分辨率分别为800×600、640×480、720×400、1024×768、1280×1024。对照VESA的标准,能体会不少事情。奇怪的是为什么不是顺序安排分辨率的,有什么深意吗,还是EDK的开发者就是这么随意?

百度云链接:https://pan.baidu.com/s/1gccSosw8_UAGTI5gZPnLCA
提取码:dx23
代码在 02 GraphicsOutput下

67 total views, 4 views today

发表评论

电子邮件地址不会被公开。 必填项已用*标注