UEFI开发探索35 – Option ROM前传2

在Legacy BIOS的Option ROM开发过程中,除了需要注意代码结构外,代码生成文件的大小也得小心,BIOS文件预留的空间不多。我一般将生成文件控制在12K左右。

当然,在后期的产品开发中,我们开始与联想和方正合作,Option ROM文件是请BIOS工程师编译进BIOS的,上述的限制就不需要那么严格了。

1 校验和的问题

Option ROM文件,要求字节校验和必须为0。而在隔离卡销售过程中发现,有些BIOS要求字校验和为0。

所谓字节校验和,也即把文件的内容一个字节一个字节加起来,其和为0;而字校验和则是按字为单位加起来,其和为0。

这种工具没有现成的,必须自己编写。

问题来了,怎么保证一个文件同时满足字节校验和以及字校验和为零?

继续阅读“UEFI开发探索35 – Option ROM前传2”

34 total views, 3 views today

UEFI开发探索34 – Option ROM前传1

下面开始进入系列博客的主线-Option ROM的开发。

我预备用3篇将这个问题说清楚。包括Legacy BIOS下的Oprom,以及如何搭建UEFI下Oprom,包含为了开发Oprom我所自制的几个工具。

我曾经有很长一段时间与Legacy BIOS的Option ROM打交道,在没有示例程序、没有人指点的情况下,苦苦探索,痛苦而又充实。

一切都从这个文档开始:

图1 pnp bios spec
继续阅读“UEFI开发探索34 – Option ROM前传1”

27 total views, 1 views today

UEFI开发探索33 – 再谈串口通信

UEFI系列博客的第20篇中,曾经尝试过构建串口通信的代码。发送串口数据在当时已经实现了,可是没有找到如何判断是否有可读的数据,读取串口没有成功。偶尔能读到串口数据,只能证明读函数起作用了。

在多年的开发经历中,我曾经开发过各种MCU的串口代码,也在DOS和Legacy BIOS下开发过。读取串口,基本都是使用中断(或者配合DMA)方式。Windows下的串口,虽然表面是Windows的消息机制,驱动层还是使用了中断。

开发过一款串口通信的隔离卡,我构建了Legacy BIOS下的底层串口和单片机的串口程序:

图1 Legacy BIOS:串口通信

虽然寄存器众多,不过核心思想还是不变:设置串口参数,设定中断处理程序,然后建立读写的函数。

可是,UEFI下只提供了Event的方式,而SerialIO Protocol中并没有对应的事件函数(类似键盘的WaitForKey)。该怎么解决这个问题?

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

319 total views, 2 views today

UEFI开发探索32 – 有趣的图像特效

PhotoShop和ACD See中,有各种对图像进行特效处理的功能,我在大学的时候就很着迷,一度考虑报考图像处理相关的研究生专业。

可惜生活总是变幻无常,推着我走向了另外一条道路,曾经的梦想还没出航就搁浅了。

不过这也影响了我之后的编程生涯,在底层开发的时候,总想着搞清楚各种图像的特效是怎么实现的。

这次准备拿UEFI App来开刀。

1 灰度转换

先上效果图:

图1 灰度化图像效果图
继续阅读“UEFI开发探索32 – 有趣的图像特效”

56 total views, 1 views today

UEFI开发探索31–鼠标GUI构建

进行了上一篇博客所描述的各种实验,相关的代码基本都已经搭建好了,我们可以着手进行对GUI界面的鼠标支持了。

UEFI对开发者提供中断支持,所有异步操作都可以通过Event来完成。Simple Pointer Procotol也提供了对此机制的支持,根据文档中函数的说明,构建如下的函数:

图1 鼠标GUI函数
继续阅读“UEFI开发探索31–鼠标GUI构建”

56 total views, 2 views today

UEFI开发探索30 –鼠标初探

我的UEFI开发探索的系列博客,一直都有一根主线的存在,那就是在测试板上把UEFI的Option ROM开发出来。

回想到目前为止,总线及设备访问:PCI、Smbus、串口,都已经实现过了(串口实现不大完美,但在测试板上不需要使用);界面相关:屏幕画图、文字显示、图像(BMP、PCX、JPEG)显示,也已经完成;用户交互:键盘已经完成,鼠标还没有写。

也就是说,鼠标探索完成后,只剩下构建Option ROM架构,这条主线就完成了。

UEFI开发探索系列已经进入中期了。

继续阅读“UEFI开发探索30 –鼠标初探”

47 total views, 1 views today

UEFI开发探索29 – 图像显示(JPEG)

最近大部分时间都在研究怎么调试了。原计划的图像显示系列,落后不少进度。

之前介绍的BMP和PCX格式,都是无损压缩格式。今天想研究下有损压缩的明星—Jpeg格式。

本来是准备了四种格式的研究:BMP、PCX、JPEG和ICO。因为时间原因,ICO就不再继续编程了。如果未来有需要,到时再把它补上吧。

这篇博客是图像显示系列的最后一篇了。

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

55 total views, 1 views today

UEFI开发探索28 – 用Windbg建立UEFI调试环境

最近的翻译计划和博客计划严重滞后。一方面是因为有两个案子在推进,业余时间也被占用;另外一方面,在尝试用windbg搭建调试环境的时候,遇到了一些阻碍。

大部分情况下,我都是使用win10的虚拟机,配合UDK2018开发的。对照文档,第一次尝试就失败了。

文档中建议的环境是Win 7/Win8 64位,UDK2010。搭建win7的虚拟机,安装Vs2008+UDK2010,再试,不行。

我怀疑虚拟机是不是会有影响,幸好公司到处都是Mini PC。下班后找了台实际机器搭建,还是不行。

在工作间隙和下班后,只要有时间,我就苦苦寻找可能性。各类操作系统,各类UDK,各版本Qemu和各版本windbg,组合起来起码也有20几种。

在我搭建这些环境的次数多到想吐,准备转到Linux下时,今天早上,竟然成功了!

冷静下来思考,发现自己有80%以上的工作,都是无用功。不过正如7个炊饼的故事一样,这些无用功才引导我尝试成功。收拾起心情,把这几天的无用功整理一下。

继续阅读“UEFI开发探索28 – 用Windbg建立UEFI调试环境”

80 total views, 1 views today

UEFI开发探索27 – 用Vs2015建立UEFI调试环境

我使用AppPkg进行Uefi app和UEFI oprom的开发,这样很方便生成在实际硬件中运行的代码。

而在日常的开发调试,不可能有硬件环境,一般会使用UEFI中生成的模拟环境,其执行文件为SecMain.exe,是在Nt32Pkg中生成的。我一般是将生成文件拷贝到其同目录下,运行SecMain.exe,进入模拟UEFI Shell执行生成文件。

当然,调试的办法仍旧是使用Print()函数,打印出需要的信息。再加上一点点想象力,以及对代码的理解,解决遇到的问题。

网上找到的资料,大部分是以Nt32Pkg为例子搭建的环境来构建调试环境。很久以前我也曾经用VS2008搭建过,可以用来编译,调试则没有成功。当时项目时间比较紧,没有去深究,用古老的Print()大法进行调试,好歹是将项目完成了。

这几天在寻找建立UEFI调试环境的过程中,发现intel其实提供了调试工具,名为UDK Debugger Tool。配合windbg和Qemu,可以搭建完整的调试环境。看到windbg,我就被吸引住了。一直觉得自己用得不熟,正好借这个机会好好深入一下。

因此,我准备花点时间用windbg来搭建调试环境。

至于用VS2015自带的调试器,我个人觉得配合SecMain也是可以搭建起来的。在尝试的过程中发现了很多可能性,有些问题我还没有想到解决办法。估计会很花时间,我暂时放弃了。

不过经验难得,我把探索VS2015建立调试环境的过程记录下来了。

1 创建Makefile Project

第一步就遇到困难了。

继续阅读“UEFI开发探索27 – 用Vs2015建立UEFI调试环境”

124 total views, 2 views today

UEFI开发探索26 – UEFI下观察汇编代码

上一篇博客中遇到了奇怪的问题,明明没有使用的函数,在编译的时候竟然报错,提示使用了此函数,而且导致程序无法链接。

这让我意识到,还是得建立完整的调试环境,帮助学习开发。

一直以来,我调试代码的方法大概有三种:

1) 打印输出。这是最常用的,也最方便的。不管是通过屏幕打印输出,还是通过串口、USB口等硬件设备打印,都能知道很多程序的内部信息;
2) 观察汇编代码。 主要用来准确的知道程序内部运行状况、库的链接、各种变量等,配合map、lst等文件综合分析。用来解决一些疑难杂症;
3) 断点调试。  这是最好的调试方法,不过视开发的产品,有时候很难实现。如果是调试Windows driver&app,VS系列产品以及Windbg能发挥很大作用;Linux下用gdb,也很好;调试DOS和Legacy bios时,我用debug.exe较多。开发固件代码时就比较麻烦了,要么用软件模拟器调试,要么用JTAG调试。

帮朋友打个小广告,建议读一读张银奎的《软件调试》, 目前他在筹划第二版四卷本的计划。第二版的第一卷已经出版,值得好好读一读。承张老师惠赠一本,正在拜读:

图1 软件调试第二版 卷1

UEFI下开发APP和Driver,以及我目前的目标Option ROM,在实际硬件中是没法使用断点调试的,至少目前我没有找到方法。实在很怀念用debug.exe调试DOS程序的日子,工具虽然简单,该有的功能都有,UEFI下怎么就没提供这种类似的工具呢?

我准备用几篇博客,谈一谈如何建立第二种观察汇编代码和第三种断点调试的方法。当然,断点调试只能在TianoCore(模拟环境)配合下工作,实际硬件就无能为力了。这就足够了,能大大加快各种代码的开发。

这篇介绍如何去观察汇编代码。

继续阅读“UEFI开发探索26 – UEFI下观察汇编代码”

428 total views, 2 views today

UEFI开发探索25 – 图像显示(PCX)

隔离卡的界面开发中,PCX实际上用得最多。主要是因为它采用了RLE压缩,在颜色不多的情况下,能够比较小。这也逼着我使用各种工具,比如PS、ACDSEE甚至是画图软件,来调整其色彩数,以减少图像尺寸。

毕竟隔离卡的ROM只有64K可用,因此常用的是256色PCX。PCX其实也支持24位真彩色,本篇中我尝试在UEFI Shell下显示24位真彩色PCX文件。

1 PCX格式介绍

PCX文件包含三部分:

  1. 文件头128字节,包含各种信息;
  2. 压缩图像数据部分,任意大小;
  3. 结尾一般带有256色的调色板,供768字节;

文件头如下:

图1 PCX结构

PCX的格式相对比较古老了,这里有篇文档可以参考一下:http://techheap.packetizer.com/compression/graphics/pcxfmt.html

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

118 total views, 1 views today

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)”

73 total views, no views today

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

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

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

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

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

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

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

88 total views, no views today

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

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

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

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

102 total views, no 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通信”

57 total views, 1 views today

UEFI开发探索20 – 串口通信

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

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

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

1 Shell命令查看串口

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

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

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

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

70 total views, no views today