请保留-> 【原文: https://blog.csdn.net/luobing4365 和 http://yiiyee.cn/blog/author/luobing/】
在开发板YIE001上进行开发,实际上和之前博客中开发UEFI应用,并没有本质的区别。所要注意的,是在Option ROM被BIOS加载之时,所用的UEFI机制以及Protocol是否能正常使用。
一般来说, GraphicsOutput Protocol和ConOut Protocol是可以正常使用的。但是,其他的Protocol,比如创建Event,就很难说了。笔者目前测试的机器上,在加载Option ROM时,创建的Event完全无法按照预期运作。而同样的代码,在同一机器的UEFI Shell下测试却是正常的。
本篇代码的编程过程如下。
1 图形支持和汉字支持
UEFI开发探索中的代码,特别是图形和汉字部分,是从我的开源项目Foxdisk中移植过来的。针对UEFI的机制,进行了改动。所以,在博客中的代码,同文件名的,其内容都差不多。
当然,随着各个课题的展开,代码也在不断地修改。甚至对我而言,也很难分清楚目前所用的文件是什么时候修改的。比如近期又在处理键盘的源文件中,添加了检查键盘按键的非阻塞处理函数CheckKey()。
我尽力维持一个松散而逻辑一致的结构,保证源文件可以直接使用。处理同一硬件的或者同一逻辑层的代码,基本上会在相同的源文件中。
以下列出了源文件的功能:
表1 源文件的功能
源文件 | 引脚名称 |
---|---|
Graphic.c, Graphic.h | 功能 |
Keyboard.c, Keyboard.h | 键盘处理 |
Window.c, Window.h | 界面相关的代码,比如背景设置等 |
Font.c, Font.h | 文字的显示,包括汉字、英文的显示 |
Common.c, Common.h | 提供各种Protocol实例,以及共用的一些函数 |
将以上的文件,拷贝到之前构建好的Option ROM框架代码的文件夹下,修改相应的INF文件,就可以直接使用了。
对于汉字的显示机制,之前的博客中已经讨论得比较多了,可以查看下之前的博客及代码。
不过,博客中讨论的议题还是比较分散的。《UEFI编程实践》的书中,为了编译阅读,将这些议题整理成章了。考虑到版权问题,各种汉字库的提取工具也重新编写了。新书发布的时候,我将会把代码和工具在Gitee和GitHub上共享,有兴趣的技术同好到时可以直接去下载使用。
2 界面及键盘控制编程
Option ROM的代码,只有在BIOS加载到内存中才能运行。在这点上,开发板YIE001和YIE002有很大不同,YIE001毕竟不是独立的MCU,无法独立运行。
本篇的代码,将键盘的控制与YIE001的硬件控制联系起来了。具体实现代码如下:
VOID HelloUEFI(VOID)
{
UINT64 flag;
EFI_INPUT_KEY key={0,0};
UINT8 *s_text = "Alasse' aure,"; //《魔戒》精灵语的 “你好,日安”
UINT8 *s_text1 = "欢迎进入UEFI的世界!";
UINT8 *s_text2 = "按'ESC'键退出此界面";
flag = InintGloabalProtocols(GRAPHICS_OUTPUT);
Print(L"flag=%x\n",flag);
//图形显示测试
SwitchGraphicsMode(TRUE);
SetBKG(&(gColorTable[DEEPBLUE]));
draw_string(s_text, 110, 60, &MyFontArray, &(gColorTable[WHITE]));
draw_string(s_text1, 80, 100, &MyFontArray, &(gColorTable[WHITE]));
draw_string(s_text2, 135, 140, &MyFontArray1, &(gColorTable[YELLOW]));
while(key.ScanCode!=0x17) //ESC
{
GetKey(&key);
if(key.ScanCode ==1 ) //UP
draw_string(s_text1, 80, 100, &MyFontArray, &(gColorTable[DEEPBLUE]));
else if(key.ScanCode ==2 ) //DOWN
draw_string(s_text1, 80, 100, &MyFontArray, &(gColorTable[WHITE]));
if(key.UnicodeChar == 0x31)
SetLed(MyIoBaseAddr,LED1,LEDON);
if(key.UnicodeChar == 0x32)
SetLed(MyIoBaseAddr,LED2,LEDON);
if(key.UnicodeChar == 0x33)
SetLed(MyIoBaseAddr,LED1,LEDOFF);
if(key.UnicodeChar == 0x34)
SetLed(MyIoBaseAddr,LED2,LEDOFF);
}
SetMyMode(OldGraphicsMode);
SwitchGraphicsMode(FALSE);
}
代码的逻辑并不复杂,在设置了图形模式,显示相应的提示字符后,直接进入按键获取的循环。只有接受到用户的ESC按键后,才会退出循环。
方向键的上下键用来控制屏幕上字符串s_text1的显示和消除;数字键1、2、3和4,分别用来控制LED1、LED2的亮和灭。
3 测试
编译命令如下:
C:\UEFIWorkspace>build -t VS2015x86 -p RobinPkg\RobinPkg.dsc \
-m RobinPkg\Drivers\YIE1CG\YIE1CG.inf -a X64
按照UEFI开发探索75介绍的方法,将YIE1CG.rom刷入YIE001的Flash中,并插在实际的机器上进行测试(也可以不刷入,使用UEFI开发探索71中介绍的方法,使用load命令测试)。
Option ROM的界面显示如图1所示。
通过键盘控制LED灯的演示,只能通过视频拍下转换为GIF。不过,GIF文件太大,就不贴出了。有条件的技术同好,可以按照本篇的方法,修改代码进行实验。
Gitee地址:https://gitee.com/luobing4365/uefi-explorer
项目所用ROM文件位于:/ 76 YIE1CG下
1,373 total views, 2 views today