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

(请保留-> 作者: 罗冰   https://blog.csdn.net/luobing4365)

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

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

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

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

  1. 如何组织汉字库(其他语言也一样,怎么存储字库?);
  2. 是否能在UEFI Shell下显示汉字,如何实现?
  3. 图形模式下如何显示汉字?

我所查询的资料包括UEFI Spec、《UEFI原理与编程》以及《Harnessing the uefi shell》,还有之前我自己写的一些代码。

图1 HII in the uefi spec2.8

UEFI Spec中用了三个章节来介绍HII,内容也比较丰富,真要全部看懂需要花很多时间。我还是从比较简单的入手:各种语言的字符串是怎么存储的?这也是《UEFI原理与编程》第11章首先介绍的。

我准备将书上的例程移植到我的程序中,我使用的模板程序是04 ReadKey,之前的博客中介绍过。

字符串资源的组织

字符串资源以*.uni文件来组织,使用#langdef、#string等标识符来定义字段。以这篇博客提供的example.uni(来源于《UEFI原理与编程》chap 11)为例:

#langdef en-US “English”
#langdef zh-Hans “简体中文”

#string STR_LANGUAGE_SELECT #language en-US “Select Language”
#language zh-Hans “选择语言”

其中,#langdef用于申明本字符串资源文件所支持的语言,第一个参数是字符标识符;第二个参数是该语言可显示的名字字符串。

我很好奇,以显示中文为例,虽然定义中名字字符串为“简体中文”,如果我想在shell下打印它的话,会怎么样?

估计什么都不会显示吧。这又回到了如何在UEFI Shell中显示汉字的问题了,没有提供字库,也没法显示什么。

#string用于定义字符串。第一个参数为字符串标识符,相当于变量定义;第二个参数是该语言下的字符串。

编译example.uni后生成的字符包组合,会定义在生成的AutoGen.c中,仔细研究这个文件,会了解不少东西。

需要注意的是,example.uni内部定义的字符串,在编译后,在本例中不是生成exampleStrings,而是生成了Luo2Strings。我猜测编译器是将*.inf中的BASE_NAME加上“Strings”组成的(Luo.inf中BASE_NAME为Luo2),没有去找资料证明,估计如此。

2 AutoGen.c中的字符串

*.uni编译之后的的字符串,在AutoGen.c中可以找到。

最开始,我以为中文的字符串,仍旧是以国标码的方式存储。汉字的国标码能很方便的查到,很多编辑器都提供了二进制查看的功能,直接就能查到。

我仔细读了AutoGen.c的字符串部分,Pack的首4字节为长度,剩余部分为字符串,可我怎么也没法将汉字意义一一对应起来。

突然意识到,字符串应该是以Unicode的编码存储的。代码中都是以L”xx”的形式在定义字符串,已经说明了这点,我怎么会没早点想到?

找来UCS-2的字符表,一个个查,果然对了。

图2 AutoGen.c中字符串的组织

管理字符串资源

UEFI中提供了EFI_HII_STRING_PROTOCOL管理字符串资源。具体的使用方法,可以参考上面提到的参考书,里面非常详细。

我主要使用了GetString来获取字符串,打印出来。

图3 GetString函数说明

主要关注两个参数,一是Language,制定需要显示的语言类型;二是String,相当于字符串变量名。

这篇博客提供的例子中,主要关注TestString和TestLanguage,以及使用HiiAddPackages添加字符串到数据库就行了,其他函数与Hii无关。

编译测试

将程序编译后,实现的效果如下:

图4 TianoCore模拟环境中运行程序

值得注意的是,使用Shell命令dmpstore -b,得到的信息如下:

图5 TianoCore模拟环境中支持的语言

全局变量L”PlatformLangCodes”存放的是系统所支持的全部语言,只有英语和法语。

看来程序中声明支持哪种语言,与系统变量是无关的。程序是自洽的,可以使用系统本身支持的语言,如果要显示系统不支持的语言,得自己去实现了。

Gitee地址:https://gitee.com/luobing4365/uefi-explorer
项目代码位于:/09 HiiShellPrint 下。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
This Unified Extensible Firmware Interface (hereafter known as UEFI) Specification describes an interface between the operating system (OS) and the platform firmware. UEFI was preceded by the Extensible Firmware Interface Specification 1.10 (EFI). As a result, some code and certain protocol names retain the EFI designation. Unless otherwise noted, EFI designations in this specification may be assumed to be part of UEFI. The interface is in the form of data tables that contain platform-related information, and boot and runtime service calls that are available to the OS loader and the OS. Together, these provide a standard environment for booting an OS. This specification is designed as a pure interface specification. As such, the specification defines the set of interfaces and structures that platform firmware must implement. Similarly, the specification defines the set of interfaces and structures that the OS may use in booting. How either the firmware developer chooses to implement the required elements or the OS developer chooses to make use of those interfaces and structures is an implementation decision left for the developer. The intent of this specification is to define a way for the OS and platform firmware to communicate only information necessary to support the OS boot process. This is accomplished through a formal and complete abstract specification of the software-visible interface presented to the OS by the platform and firmware. Using this formal definition, a shrink-wrap OS intended to run on platforms compatible with supported processor specifications will be able to boot on a variety of system designs without further platform or OS customization. The definition will also allow for platform innovation to introduce new features and functionality that enhance platform capability without requiring new code to be written in the OS boot sequence. Furthermore, an abstract specification opens a route to replace legacy devices and firmware code over time. New device types and associated code can provide equivalent functionality through the same defined abstract interface, again without impact on the OS boot support code. The specification is applicable to a full range of hardware platforms from mobile systems to servers. The specification provides a core set of services along with a selection of protocol interfaces. The selection of protocol interfaces can evolve over time to be optimized for various platform market segments. At the same time, the specification allows maximum extensibility and customization abilities for OEMs to allow differentiation. In this, the purpose of UEFI is to define an evolutionary path from the traditional “PC-AT”- style boot world into a legacy-API free environment.
统一可扩展固件接口(UEFI)规范描述了操作系统和平台固件之间的接口。UEFI之前是可扩展固件接口规范1.10 (EFI)。因此,一些代码和某些协议名称保留了EFI名称。除非另有说明,本规范中的EFI名称可能被认为是UEFI的一部分。 接口采用数据表的形式,其中包含与平台相关的信息,以及OS加载器和OS可用的引导和运行时服务调用。它们共同提供了一个引导操作系统的标准环境。本规范是作为一个纯粹的接口规范设计的。因此,该规范定义了平台固件必须实现的接口和结构集。类似地,该规范定义了操作系统在引导时可能使用的一组接口和结构。固件开发人员如何选择实现所需的元素,或者操作系统开发人员如何选择利用这些接口和结构,这是留给开发人员的实现决策。 该规范的目的是定义一种方法,使操作系统和平台固件仅通信支持操作系统引导过程所必需的信息。这是通过平台和固件提供给操作系统的软件可见接口的正式和完整的抽象规范来实现的。 使用这一正式定义,旨在运行在与受支持的处理器规范兼容的平台上的收缩包装操作系统将能够在各种系统设计上启动,而无需进一步的平台或操作系统定制。该定义还允许平台创新引入新特性和功能,以增强平台的能力,而不需要按照操作系统的引导顺序编写新代码。 此外,抽象规范开辟了一条替代遗留设备和固件代码的路径。新的设备类型和相关代码可以通过相同定义的抽象接口提供同等的功能,同样不会影响OS引导支持代码。 该规范适用于从移动系统到服务器的所有硬件平台。该规范提供了一组核心服务以及一组协议接口。协议接口的选择可以随着时间的推移而发展,并针对不同的平台市场细分进行优化。与此同时,该规范允许oem提供最大限度的可扩展性和定制能力,以实现差异化。在这方面,UEFI的目的是定义一个从传统的“PC-AT”风格的引导世界到一个没有遗留api的环境的进化路径。
This Unified Extensible Firmware Interface (UEFI) Specification describes an interface between the operating system (OS) and the platform firmware. UEFI was preceded by the Extensible Firmware Interface Specification 1.10 (EFI). As a result, some code and certain protocol names retain the EFI designation. Unless otherwise noted, EFI designations in this specification may be assumed to be part of UEFI. The interface is in the form of data tables that contain platform-related information, and boot and runtime service calls that are available to the OS loader and the OS. Together, these provide a standard environment for booting an OS. This specification is designed as a pure interface specification. As such, the specification defines the set of interfaces and structures that platform firmware must implement. Similarly, the specification defines the set of interfaces and structures that the OS may use in booting. How either the firmware developer chooses to implement the required elements or the OS developer chooses to make use of those interfaces and structures is an implementation decision left for the developer. The intent of this specification is to define a way for the OS and platform firmware to communicate only information necessary to support the OS boot process. This is accomplished through a formal and complete abstract specification of the software-visible interface presented to the OS by the platform and firmware. Using this formal definition, a shrink-wrap OS intended to run on platforms compatible with supported processor specifications will be able to boot on a variety of system designs without further platform or OS customization. The definition will also allow for platform innovation to introduce new features and functionality that enhance platform capability without requiring new code to be written in the OS boot sequence. Furthermore, an abstract specification opens a route to replace legacy devices and firmware code over time. New device types and associated code can provide equivalent functionality through the same defined abstract interface, again without impact on the OS boot support code. The specification is applicable to a full range of hardware platforms from mobile systems to servers. The specification provides a core set of services along with a selection of protocol interfaces. The selection of protocol interfaces can evolve over time to be optimized for various platform market segments. At the same time, the specification allows maximum extensibility and customization abilities for OEMs to allow differentiation. In this, the purpose of UEFI is to define an evolutionary path from the traditional “PC-AT”- style boot world into a legacy-API free environment.
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luobing4365

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值