UEFI开发探索24 – 图像显示(BMP)

BMP是微软推荐和支持的标准图像文件格式,图像数据不经过压缩直接存盘,直译过来是位图(bitmap)。

最早的时候,Windows自带的画图程序只支持bmp格式,现在缺省支持PNG了。

这种格式比较简单,数据结构也非常容易看懂。我在开发隔离卡、Option ROM以及嵌入式产品时,如果需要用到图像,只要空间允许,都是用BMP格式。代码简单,很多时候几行循环代码就搞定。

在Foxdisk的博客中,还没来得及对图像格式进行介绍。那款软件中主要使用了BMP和PCX两种图像格式。

我预备用几篇博客,把常用的图像格式在UEFI Shell下如何显示介绍一下。为了方便,没有使用main函数作为入口,而是使用了ShellAppMian。理由比较简单,main函数入口参数不是Unicode的,需要进行转换;另外,我也想尽可能使用UEFI提供的函数来进行处理,尽量少用标准C的库函数。

先从BMP开始。

继续阅读“UEFI开发探索24 – 图像显示(BMP)”

111 total views, 2 views today

UEFI开发探索23 – File IO(文件读写)

Option ROM的开发中,很少用到文件读写。因此,在最早开发的过程中,我没有仔细研究过文件处理相关的Protocol。

倒是在编写显示图片例程的时候,涉及到了一些。我直接使用了UDK中的例子,改造了显示BMP的函数,函数内部封装了文件读取。

接下来我准备用几篇博客,演示如何显示图片。UEFI画图的程序,在之前的博客中已经讨论演示过了。下面需要做的,是解析图像格式,解压数据,并通过画图函数将其显示在屏幕上。

预备要处理的图像格式包括BMP、PCX,有时间的话研究下Jpeg。

当然,首先还得搞清楚UEFI下怎么进行文件读写。

继续阅读“UEFI开发探索23 – File IO(文件读写)”

126 total views, 1 views today

UEFI开发探索22 – 环境搭建3

之前搭建UDK2017和UDK2018失败,我只能使用以前的开发环境WinXP+UDK2010来调试程序。总感觉自己像个史前程序员,XP下很多工具都没法使用的。比如我想看某个函数的定义,只能使用TotalCmd全文件夹搜索,感觉很不爽。

今天去公司加班,广州有客人来访。下午送走客人后,我盯着以前写的“搭建环境”的博客,下定决心,一定要用上win10+UDK2018为新的开发环境。

继续阅读“UEFI开发探索22 – 环境搭建3”

169 total views, 1 views today

UEFI开发探索21 – SMBUS通信

SMBus是1995年由Intel提出的一种双线通信专利技术,它完全符合系统管理总线规范1.1版,与I2C串行总线兼容。与当前流行的高速串行协议相比,SMBus的速度比较慢,但因其使用硬件少,支持此协议的产品非常多,在当前的计算机行业仍然有很大的应用面。

在开发双网隔离计算机的过程中,需要解决三方通信问题。即Windows/Linux层App、控制卡Firmware和BIOS(包括BIOS oprom)三方的通信。实际上需要解决的是控制卡Firmware与Windows/Linux层App、控制卡Firmware与BIOS通信的问题。

最早我采用PCI/PCIE芯片。问题是厂商提供的驱动不完善,总是有各种问题;加上芯片上的控制引脚不够,无法实现产品目标。

后期换为C8051F320,价格也比较合适。底层的通信(控制卡Firmware与BIOS)定为SMBUS总线通信方式;上层的通信则使用了USB HID协议。

由此开始了我辗转在各种平台上开发SMBUS通信代码的历程。

继续阅读“UEFI开发探索21 – SMBUS通信”

97 total views, no views today

UEFI开发探索20 – 串口通信

串口可能是生命力最强的接口标准了,从1980年到现在,仍旧在发挥巨大的作用。特别是工业环境下,可说是王者标准了。

前几年开发过网络转串口,我惊奇的发现很多金融场合也在用串口。

扯远了,回到UEFI下的串口通信。

1 Shell命令查看串口

我的开发环境仍旧是虚拟机winxp+UDK2010,一直没有时间去搭建UDK2018。UEFI Shell中有个命令Sermode,可以查看以及设置串口参数。

图1 TianoCore模拟环境中枚举串口

设备管理器中有两个串口,TianoCore的模拟环境中也列出了两个串口。下面的问题是,如何与虚拟机中的串口通信?

继续阅读“UEFI开发探索20 – 串口通信”

111 total views, no views today

UEFI开发探索19 – 使用HII显示汉字4

已经实现了UEFI Shell下使用SimpleFont和Font,在Graphics模式下来实现就相对容易很多了。

我大部分的工作都是在整理文件,以及按照之前的代码结构,专为Hii构建了源代码文件,把一些细节封装起来,以备后用。

图1 整理好的源代码

可以讲解的地方不多,主要是在开发中遇到的一些问题:

继续阅读“UEFI开发探索19 – 使用HII显示汉字4”

69 total views, no views today

UEFI开发探索18 – 使用HII显示汉字3

本篇博客的关键字:Font。

今天准备把UEFI另外一种字体Font的方方面面研究一下,仍旧是以代码移植为主,间以解决自己提的几个问题。

1 Text模式和Graphics模式

实验之前,我想谈一下Text模式和Graphics模式。UEFI spec中,对于Text模式和Graphics模式谈的比较少。我一直很疑惑,spec中的Text模式和Graphics模式是不是我所理解的。

继续阅读“UEFI开发探索18 – 使用HII显示汉字3”

97 total views, no views today

UEFI开发探索17 – 使用HII显示汉字2

本篇博客的关键字:SimpleFont。

我始终在思考如何在UEFI Shell下显示汉字。上一篇中,参考书中的例子,基本了解了字符串资源是怎么组织的。当在TestString函数中,把参数Language改为”zh-Hans”,什么也没有显示。

看来还是缺少相应的字库。

UEFI下提供了SimpleFont和Font字体,前一个相对简单些,我先拿这个开刀。我参考的例子是《UEFI原理与编程》的\GUIbasics\font\SimpleFont,这个例子直接编译没有成功。我也没有去找原因,还是老办法,把它的例程移植到我自己的程序中来。

1 SimpleFont格式

SimpleFont有两种字体格式,窄字符和宽字符,在书中描述得很清楚。TianoCore的模拟环境中,也使用了SimpleFont的字库。

继续阅读“UEFI开发探索17 – 使用HII显示汉字2”

101 total views, 1 views today

UEFI开发探索16 – 使用HII显示汉字1

上一次博客中,我使用自己的方法显示汉字,其核心思想不外乎利用实现的画点函数,将汉字一个像素一个像素地画出来。

很明显,这种方法只能在图形模式下实现。如果想在字符模式下显示(比如UEFI Shell),则无能无力了。虽然目前商用的Option Rom不可能用到字符模式,奈何寻根究底的程序员本性,驱使着我把UEFI本身提供的Human Interface Infrastructure机制搞明白。

于是开始了我这几天的探索之旅。

所有的探索都是从问题开始,对HII,我提的问题如下:

  1. 如何组织汉字库(其他语言也一样,怎么存储字库?);
  2. 是否能在UEFI Shell下显示汉字,如何实现?
  3. 图形模式下如何显示汉字?
继续阅读“UEFI开发探索16 – 使用HII显示汉字1”

75 total views, 2 views today

UEFI开发探索15 – 图形模式下文字显示

UEFI中提供了HII(Human Interface Infrastructure)用来处理图形界面的文字显示,这一块我一直没有去仔细研究。到目前为止,显示汉字和字符,我都没有采用这种方法。

比如之前博客中演示了测试样卡的界面,图形中用到了各种英文和汉字,都是采用我自己的方法来实现的。

HII的思考方式不大直接,当时我面临着要在几周内完成UEFI Option ROM的开发,需要克服的困难太多,图形模式下的汉字和英文字符的显示,我采用了Foxdisk中的显示方法。

具体来说,在前面的博客中,已经实现了画点函数(putpixel)函数,那么把所有汉字及英文字符看做一个个的字模,画出来就行了。所有的核心思想皆源于此。

继续阅读“UEFI开发探索15 – 图形模式下文字显示”

157 total views, 1 views today

UEFI开发探索14 – 访问PCI/PCI-E设备2

(关于PCI访问,其中一些内容来自网上,找不到出处了)

PCI规范使用从0CF8H~0CFFH 这8个I/O地址来访问所有设备的PCI配置空间。这8个字节实际上构成了两个32位寄存器:0CF8H寄存器叫做“配置地址寄存器”;0CFCH叫做“配置数据寄存器”。

当要访问配置空间的寄存器时,先向地址寄存器写上目标地址,然后就可以从数据寄存器中读写数据了。

PCI配置空间对应于一个PCI逻辑设备,所以要访问一个配置空间的某个寄存器,必须要指定:PCI总线号、PCI设备号、PCI设备功能号和寄存器号。配置地址寄存器的格式如下:

继续阅读“UEFI开发探索14 – 访问PCI/PCI-E设备2”

174 total views, 2 views today

UEFI开发探索13 – 访问PCI/PCI-E设备1

我所用的测试卡是PCI-E设备,公司商用的产品也是PCI-E设备。所以,我很早就“被迫”去读那些PCI spec。

从软件工程师的角度,我觉得只要解决几个问题就行了,其余的细节不妨碍编程。

1)      PCI/PCI-E设备是如何定位的,也即程序如何找到设备;
2)      系统把它认作什么设备;
3)      如何访问设备的内部寄存器(一般要去读所使用的PCI-E芯片的资料);
4)      商用化的产品,需要考虑设备对ACPI的各种电源事件的处理。

继续阅读“UEFI开发探索13 – 访问PCI/PCI-E设备1”

140 total views, no views today

UEFI开发探索12 – Oprom测试板

今天拿到了测试板,可以把UEFI Oprom写到硬件里面去了。手有点痒,想写一个程序来试试。

测试用的板子非常简单,去除了所有实际的硬件控制元器件,只留下了WCH366和一个128K的ROM。不过按照沁恒电子的资料,WCH366只支持64K的寻址,而且还不能同时寻址,意味着我们只有32K的空间可以写代码。

做了十个,足够我折腾很长时间了。

图1 测试用的小板卡
继续阅读“UEFI开发探索12 – Oprom测试板”

85 total views, no views today

UEFI开发探索11 – 鼠标前传

这不是写鼠标的历史,而是记录在很久以前,在Legacy BIOS下,我写鼠标驱动(BIOS/DOS下运行)的过程。

我对底层编写程序,从参加工作的时候就非常着迷。当时接手隔离卡5.0的开发维护,主体产品已经完成,我一直思考:怎么才能让产品和别家的不同呢?

介绍下背景知识:隔离卡V5.0是公司第一款采用PCI Oprom开发的产品,插上就可以出界面。省去了用户安装软件的过程,一推出就大受欢迎。我们采用的是沁恒电子的WCH365,代码也参考他们的DEMO开发的。很快,对手使用同样的芯片,有了同样的方案。

就是在这种情况下,我希望找到新的竞争点。突然想到,市场上所有的PCI Option ROM上的界面,都是支持键盘的,没有支持鼠标的。这不就是一个切入点吗?如图,这是当时的隔离卡。我工作的笔记本没带回来,图是从网上找到的,这么多年,没想到还能找到。

图1 易思克隔离卡v5.0

有了想法,执行起来也不容易。

问题1: 鼠标肯定是在图形模式下运行的,怎么无缝的将鼠标显示在目前的界面?
问题2: 针对鼠标的驱动代码量不能大,ROM只有32K,现在出货的产品已经有21.5K,留给鼠标驱动的就没有多少空间,必须控制代码量;
问题3: 我知道DOS下有int33h可以控制鼠标,也有大量的例子可以参考。可惜我们是在BIOS上运行的,无法调用;

继续阅读“UEFI开发探索11 – 鼠标前传”

110 total views, 2 views today

UEFI开发探索10 – 再论键盘

突然想起一句诗:戍客望边色,思归多苦颜。也许是天气原因,也许是出差,心情总是不好。

上海的天空,灰蒙蒙的。一眼望去,都是淡墨色的乌云,不沉重,也透不过阳光。窗外的风很小,茂盛的树叶一动不动。除了传来的汽车声音,几乎要怀疑时间停止了一样。

没有阳光的天气,让人心情比较压抑。

继续阅读“UEFI开发探索10 – 再论键盘”

109 total views, 1 views today

UEFI开发探索09 – 图形显示02

上次对UEFI的图形模式有了一定的了解,根据得到的信息,我准备用1024×768的分辨率来运行程序。

这个分辨率我比较熟悉,以前的代码(legacy bios下)可以复用。在Vesa标准中,有多个模式是这个分辨率的(我最常用的是105h)。如图:

图1 VESA graphics

那么UEFI的这个分辨率对应的是哪个模式呢(UEFI 下的模式索引值为3)?虽然都是从EDID中读出来的,不过经过了UEFI 的重组,我也搞不清到底是对应哪个。从blt的操作方式来看,可能是118h;不过似乎其他的模式也能类似操作。

算了,不纠结了,什么时候去跟下代码就知道了。

继续阅读“UEFI开发探索09 – 图形显示02”

93 total views, 1 views today