UEFI开发探索41 – Event、Timer和任务优先级

(请保留->发布地址: http://yiiyee.cn/blog/author/luobing/ )

作为一个底层的支持系统,UEFI没有支持中断。如果想支持异步操作,只能通过事件(Event)来实现。

在开发Foxdisk的过程中,也遇到需要同时处理的事件。比如提示用户输入的闪烁光标、自动显示的系统时间等,我是采用了时钟中断(int 1Ch)的方式来实现的,是段很有意思的程序。

不过,我只是简单地将需要的功能堆砌在int 1Ch中实现,并没有完整地实现多任务间的互斥,是一种“伪多任务”的实现。那么,UEFI中是怎么来支持多个任务同时执行呢?

1 支持的服务函数

图1为相关的服务函数,总共10个:

图1 事件相关服务函数
继续阅读“UEFI开发探索41 – Event、Timer和任务优先级”

290 total views, 1 views today

UEFI开发探索40 – 构建自己的Package

前段时间在Linux下开发UEFI程序,发现以前写的AppPkg的32位程序没法编译,无法在模拟环境下测试执行程序。

我当时就想脱离AppPkg,自己构建Package。当然,StdLib的库不能使用了,也不能以main()函数为入口。我觉得这都不是什么大事,毕竟平常构建的Option ROM代码也不能使用这些。

说干就干,顺便把各种类型文件的知识点过一遍。

1 编译框架

EDKII的编译系统是基于Python和C的代码构建的,可以跨平台编译。也可运行在不同的CPU架构上,比如X86和ARM,最近我们在做针对龙芯MIPS的软件,乐见UEFI发展版图的扩大。

图1 EDKII 工作流程
继续阅读“UEFI开发探索40 – 构建自己的Package”

103 total views, 1 views today

UEFI开发探索39 – Ubuntu 16.04下用gdb建立UEFI调试环境

准确地说,应该是在Ubuntu 16.04下,使用Qemu模拟UEFI启动环境,同时配合Intel UDK Debugger tool和gdb建立的X64调试环境。

使用的是Qemu和OvmfPkg,类似于之前使用windbg在Windows下搭建调试环境,这次换为在Linux下搭建了。正是上一篇博客留下的题目。

1 参考资料

如何在Linux下搭建调试环境,网上的资料不多,特别是如何让gdb挂上UEFI启动环境,我摸索了几天。

可供参考的资料有《UDK_Debugger_Tool_User_Manual_V1.11.pdf》,在网站https://firmware.intel.com/develop/intel-uefi-tools-and-utilities/intel-uefi-development-kit-debugger-tool上下载,其中第六章开始介绍如何在Linux下搭建调试环境。

以及开源项目Slim Bootloader: https://slimbootloader.github.io/index.html。它在调试的时候使用了UDK Debugger Tool,搭建调试环境的方法可用来类比。

图1 Slim Bootloader’s LOGO
继续阅读“UEFI开发探索39 – Ubuntu 16.04下用gdb建立UEFI调试环境”

119 total views, 1 views today

UEFI开发探索38 – Ubuntu下编译AppPkg杂谈

上一篇博客中,在编译AppPkg的时候,遇到了问题,编译的时候出错。错误的提示在上一篇博客中贴出来了,这里不再贴出。针对此问题,我查找了一些资料,做了若干实验,姑且以杂谈的形式记录下来。

1 EADK

为了方便使用标准的C库,EDKII中提供了开发包:EDK II Application Development Kit,简称为EADK。它最早脱胎于EFI_ToolKit,是Intel推广EFI的范例程序包。

随着UEFI的法发展,原来的架构无法统一,EFI_ToolKit的代码被分别整合到各个Package中了。其中的python和Application Development Kit就由EADK接替,并维护着。不过,从github上的日期来看,最后维护的时间也是2015了,是不是后面放弃了?

不管如何,它能很方便的用来构建Uefi程序,也能直接使用熟悉的C库函数,之前博客中的大量代码都使用了它。 它包含了三个Package:

图1 EADK
继续阅读“UEFI开发探索38 – Ubuntu下编译AppPkg杂谈”

101 total views, no views today

UEFI开发探索37 – Linux下环境搭建

Windows下搭建环境、编译、运行等一系列工作,都已经比较熟练了。不过,鉴于Intel提供的调试工具(之前博客中讲述过)Linux版本的都比windows新:

图1 已经两年没更新的调试工具

我觉得还是有必要在Linux下把开发环境建立起来。何况,我平常用来开发UEFI的Windows虚拟机实在太大了,动辄50G,装完必要软件后,只剩下10多个G。

继续阅读“UEFI开发探索37 – Linux下环境搭建”

124 total views, no views today

UEFI开发探索Q&A – 问题辑录(持续更新)

最近正在尝试在Unbutu16上搭建开发和调试环境,其中过程一言难尽,到现在也没完成到符合我要求的程度。

正是因为遇到障碍,我今天早上回到Win10+UDK2018的环境下,想重新编译下AppPkg,没想到遇到问题了,怎么编译都不通过。明明之前是没有问题的啊,看第26篇博客,当时我还非常雀跃于第一次编译通过。

我一直都在使用AppPkg编译我自己的UEFI app,肯定是哪里的配置被我自己修改,忘记了。一番折腾后,终于搞清楚了。

基于上面的事故,我觉得有必要专门做一个问题辑录的博客,把自己遇到的一些比较奇怪的问题以及解决方法记录下来。

这篇博客用来占坑,遇到问题就到这里记录,估计会很长……

继续阅读“UEFI开发探索Q&A – 问题辑录(持续更新)”

90 total views, no views today

UEFI开发探索36 – UEFI Option ROM

Option ROM的开发不是一门显学,相关的资料也少得可怜。如果是在ODM厂商工作,或者做BIOS相关的工作,可以接触到很多相关的材料。不过,对我这种必须开发Option ROM,公司又不是相关行业的,非常少见。这也导致在开发Legacy BIOS的Oprom时,只能一点点摸索,遇到的问题如山之多。

UEFI下开发Option ROM相对好多了,一方面资料比较全面,EDK的文档组织还是比较明晰的;另一方面,它也提供了标准的工具,非常便利。我自己的测试卡是PCIE接口的,接下来讨论的Option ROM是针对PCI扩展ROM的(ISA ROM在UEFI spec中好像不支持了)。

UEFI的Option ROM结构与之前介绍的Legacy BIOS Oprom类似:

图1 UEFI Option ROM结构(From UEFI Spec 2.8 page 723)
继续阅读“UEFI开发探索36 – UEFI Option ROM”

193 total views, no views today

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”

123 total views, no 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”

445 total views, no views today

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

(请保留->发布地址: http://yiiyee.cn/blog/author/luobing/ )

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

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

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

图1 Legacy BIOS:串口通信

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

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

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

413 total views, no views today

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

(请保留->发布地址: http://yiiyee.cn/blog/author/luobing/ )

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

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

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

这次准备拿UEFI App来开刀。

1 灰度转换

先上效果图:

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

166 total views, 1 views today

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

(请保留->发布地址: http://yiiyee.cn/blog/author/luobing/ )

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

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

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

136 total views, no views today

UEFI开发探索30 –鼠标初探

(请保留->发布地址: http://yiiyee.cn/blog/author/luobing/ )

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

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

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

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

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

140 total views, no views today

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

(请保留->发布地址: http://yiiyee.cn/blog/author/luobing/ )

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

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

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

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

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

156 total views, no views today

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

(请保留->发布地址: http://yiiyee.cn/blog/author/luobing/ )

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

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

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

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

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

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

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

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

265 total views, 1 views today

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

(请保留->发布地址: http://yiiyee.cn/blog/author/luobing/ )

我使用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调试环境”

279 total views, 1 views today