UEFI开发探索55 – UEFI与网络5(IPv6)

请保留-> 【原文:  https://blog.csdn.net/luobing4365http://yiiyee.cn/blog/author/luobing/】

本篇开始编写IPV6的代码。因为一直使用的网络调试助手不支持IPV6的通信,只好花了点时间,自己把相关的IPV6的代码(windows和linux下)实现了一遍。

1 搭建IPV6的通信环境

由于现在基本上还在使用IPV4的网络,特别是家庭中,很少使用支持IPV6的路由器。所以,如果需要在双机间调试IPV6的代码,最好买个支持IPV6的路由器,按照路由器手册设置一下就可以了。

当然,我们也可以虚拟机来搭建通信环境。我所使用的虚拟机,都是使用NAT模式的。在打开IPV6支持选项前,虚拟机操作系统上的网卡,没有分配对外的IPV6的地址,导致无法与宿主机通信。

做个类比,开启虚拟机的IPV6支持选项,相当于为虚拟机添加了IPV6的路由器。虚拟机操作系统上的网卡设备会分配IPV6地址,虚拟机之间、虚拟机和宿主机之间可以通过IPV6通信。

记录下Vmware和VirtualBox打开IPV6的方法。

继续阅读“UEFI开发探索55 – UEFI与网络5(IPv6)”

3,333 total views, 1 views today

UEFI开发探索54 – UEFI与网络4(IPv4)

请保留-> 【原文:  https://blog.csdn.net/luobing4365http://yiiyee.cn/blog/author/luobing/】

本篇主要讨论怎么使用StdLib的库函数编写TCP4的代码。

上一篇中直接使用UEFI提供的TCP4 Protocol编写代码,比较复杂,需要自己重新构建所有代码。我们还是希望能够直接使用标准的Socket库来编程,这样可以直接复用以前编写的Socket代码,减少编程的工作量。

1 BSD Socket接口

StdLib中提供的是标准BSD Socket接口,允许不同主机或同一计算机的不同进程之间的通信,是事实上的连接互联网的标准接口。

BSD Socket中要求的API接口,在UEFI的实现中基本都提供了。主要的头文件如下(StdLib\Include下):

<sys/socket.h>  socket 的核心函数和数据结构;
<netinet/in.h>  互联网地址族,AF_INET 和AF_INET6 地址家族和他们对应的协议家族 PF_INET 和 PF_INET6,包括IP地址以及TCP和UDP端口号;
<arpa/inet.h> 和IP地址相关的一些函数,比如地址转换的inet_pton()等;

由于UEFI并非完整的操作系统,也有很多BSD Socket中的API没有实现,比如针对计算机上程序间的本地通信的un.h。这些没有实现的函数,大部分是与网络通信无关,对我们的UEFI网络编程影响不大。

继续阅读“UEFI开发探索54 – UEFI与网络4(IPv4)”

3,829 total views, no views today

UEFI开发探索53 – VS2015调试UEFI代码(续第27篇)

请保留-> 【原文:  https://blog.csdn.net/luobing4365http://yiiyee.cn/blog/author/luobing/】

在开发网络代码的时候,光用Print打印信息不足以满足开发要求,必须源代码级别的跟踪。我所测试的环境,大部分是在TianCore的模拟环境下。因此,如何在这个环境中,实现源码级跟踪,成为了很迫切的需求。

当然,我可以在Linux下开发,使用Qemu+gdb的方式来调试。不过,每次都要编译好,然后拷贝到镜像文件中,再启动调试,略嫌麻烦。我还是希望能在Windows下,使用VS来调试。

之前的博客第27篇中,我已经介绍了如何使用Vs2015搭建UEFI调试环境。经过这几天的学习,发现之前的有些结论有点偏差,所以再写一篇作为补充。

以我的经验,使用Nt32Pkg编译出来的模拟环境,配合VS2015自带的调试器,能满足我至少90%以上的开发需求。除去那些必须要在硬件上调试,只能使用windbg/gdb进行双机调试之外,这是目前为止最好的调试方法了。

上一篇讨论Vs2015调试环境中,谈到使用AppPkg编译的代码,无法进行源代码级调试,这个结论有点问题。实际上,只要做一些调整,是可以解决这个问题的。

继续阅读“UEFI开发探索53 – VS2015调试UEFI代码(续第27篇)”

2,336 total views, no views today

UEFI开发探索52 – UEFI与网络3(UEFI TCP4)

请保留-> 【原文:  https://blog.csdn.net/luobing4365http://yiiyee.cn/blog/author/luobing/】

搭建好网络测试环境之后,可以着手进行网络编程了。

UEFI下提供了相应的Protocol,可以进行TCP和UDP的编程,而且针对IPv4和IPv6都提供了相应的支持。另外,也可以通过StdLib中封装好的Socket接口进行编程。

如果所有的编程方式都实现一遍,博客的篇幅就太长了。我原计划是用5篇左右的博客,把网络编程探索完的,因此,我准备用UEFI Protocol编写TCP(IPv4)示例和UDP(IPv4) 示例,以及StdLib接口把上述例子重新实现。

1 EFI_TCP4_PROTOCOL的使用

大部分的UEFI Protocol,可通过设备的GUID找到,直接访问即可。与其他UEFI Protocol不同,网络需要频繁地生成新的Socket。在规范中,针TCP4,提供了两种Protocol。

一是EFI_TCP4_PROTOCOL,可以进行TCP的网络配置和通讯;二是EFI_TCP4_SERVICE_BINDING_PROTOCOL,用来生成EFI_TCP4_PROTOCOL实例。

不过,在EDK2的实现中,并没有提供EFI_TCP4_SERVICE_BINDING_PROTOCOL,而是为所有的网络协议提供了EFI_SERVICE_BINDING_PROTOCOL。也就是说,虽然在Spec中提供了各种名为EFI_XXXX_SERVICE_BINDING_PROTOCOL的协议,其实都是使用EFI_SERVICE_BINDING_PROTOCOL。

继续阅读“UEFI开发探索52 – UEFI与网络3(UEFI TCP4)”

5,341 total views, no views today

UEFI开发探索51 – UEFI下的打印函数

请保留-> 【原文:  https://blog.csdn.net/luobing4365http://yiiyee.cn/blog/author/luobing/】

原计划的50篇博客,终于完成了。可惜的是,现有的篇幅无法把最初设想的内容全部覆盖。因此,开发探索系列还会继续写下去,既然原定目标50篇已经达成,新的目标篇数就不设定了。只针对我感兴趣的各方面的内容,继续探索。

在日常的开发中,总会用到各种打印(print)函数。UEFI下的打印函数,其格式有点奇怪,和Windows及Linux下的print函数不大相同。而且又涉及到Ascii字符和Unicode字符的支持,在使用中总是犯一些小错,让人很是恼火。

因此,为了方便后面的开发,我准备将相关的打印函数整理出来,以备参考。

1OutputString()

最基本的打印输出函数,其他Print函数都是基于此函数构建的。其函数原型为:

typedef
EFI_STATUS
(EFIAPI *EFI_TEXT_STRING) (
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This,//指向    
                                 //EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
实例的指针
IN CHAR16 *String //Null结尾的字符串
);

此函数向输出设备写入字符串,显示在当前光标处,是最基本的输出机制。

示例如下:

gST->ConOut->OutputString(gST->ConOut,L”Hello, UEFI World!\n\r”);

这是Simple Text Output Protocol最核心的函数,配合此Protocol的其他函数,比如SetAttribute等,可以实现彩色背景和彩色字体。在之前的博客中曾经展示过,可以做出与众不同的命令行式Sell程序。

2 格式化输出

PrintLib提供了格式化输出的支持函数,它支持所有Unicode和ASCII字符串。在Package的dsc文件中,一般都会提供这个库的编译。如下:

PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf

UEFI的格式化方式,与ANSI C的标准不尽相同,在使用的时候,很容易造成概念混淆。

格式化语法如下:

%[flags][width][.precision]type

继续阅读“UEFI开发探索51 – UEFI下的打印函数”

9,062 total views, no views today

UEFI开发探索50 – UEFI与网络2

请保留-> 【原文:  https://blog.csdn.net/luobing4365http://yiiyee.cn/blog/author/luobing/】

3 在VirtualBox中使用网络

在UEFI开发探索系列博客的第48篇中,我介绍了如何在VirtualBox中搭建UEFI Shell。本节就在这篇博客的基础上,让VirtualBox下的UEFI Shell有访问网络的功能。

1) 安装网络驱动和网络协议驱动

我使用的是VirtualBox6.1.4,其虚拟网卡为Intel Pro/1000MT Desktop。网卡驱动下载地址为:

https://downloadcenter.intel.com/download/27539/Ethernet-Intel-Ethernet-Connections-Boot-Utility-Preboot-Images-and-EFI-Drivers

下载版本为22.10的PREBOOT.exe,双击安装。将目录/APPS/EIF/EFIx64下的驱动E3522X2.EFI拷贝到虚拟机的硬盘中。同时,将之前编译好x64的Ipv4网络协议驱动(MdeModulePkg)也拷贝到虚拟机的硬盘中。

启动虚拟机,进入UEFI Shell,执行如下命令,加载网卡驱动和网络协议驱动:

Shell>fs0:
fs0:>load E3522X2.EFI
fs0:> load SnpDxe.efi MnpDxe.efi ArpDxe.efi Ip4Dxe.efi VlanConfigDxe.efi Udp4Dxe.efi Dhcp4Dxe.efi Mtftp4Dxe.efi Tcp4Dxe.efi

2) 配置网卡。

使用ifconfig命令设置:

fs0:\>ifconfig -s eth0 dhcp

检查网络配置情况:

图1 VirtualBox的UEFI Shell中查看IP
继续阅读“UEFI开发探索50 – UEFI与网络2”

3,144 total views, no views today

UEFI开发探索49 – UEFI与网络1

请保留-> 【原文:  https://blog.csdn.net/luobing4365http://yiiyee.cn/blog/author/luobing/】

UEFI提供了非常完整的TCP/IP网络协议栈,开发人员甚至可以在UEFI上开发自己的Web服务器。其网络协议栈如图1所示:

图1 UEFI的网络协议栈
继续阅读“UEFI开发探索49 – UEFI与网络1”

6,391 total views, 1 views today

UEFI开发探索48 – 搭建UEFI Shell环境

请保留-> 【原文:  https://blog.csdn.net/luobing4365http://yiiyee.cn/blog/author/luobing/】

做UEFI的实验,32位的程序可以使用TianoCore的模拟环境进行测试。64位的程序,可以使用启动盘在实际的机器上测试,也可以使用虚拟机来测试。

制作启动盘很简单,不过,我之前保存的启动文件丢失了,正好重新做一遍,把过程记录下来。

1 制作UEFI BIOS下的启动盘

启动文件可以通过编译ShellPkg来得到。打开VS命令行,进入EDK的目录,执行edksetup.bat后,输入以下命令:

build -a IA32 -a X64 -p ShellPkg\ShellPkg.dsc -b RELEASE

在EDK的Build\Shell\RELEASE_VS2015x86目录下,会生成32位和64位的完整shell执行文件。

然后执行以下步骤:

1) 将U盘格式化为FAT32(FAT、FAT16也可以,现在很少使用了)格式;

2) 在U盘的根目录下建立efi\boot文件夹;

3) 将刚才生成的两个32位和64位shell执行文件(名称都是Shell.efi),分别改名为bootx32.efi和bootx64.efi,拷贝到U盘的efi\boot目录下。

做好的U盘插到计算机上,开机的时候选择从U盘启动(每款BIOS不大一样,常见的可以按F11选择启动项,或者进入Bios Setup设置从U盘启动),即可进入UEFI shell了。

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

4,989 total views, no views today

UEFI开发探索47 – UEFI上移植GUILite

请保留-> 【原文:  https://blog.csdn.net/luobing4365http://yiiyee.cn/blog/author/luobing/】

上一篇的博客中,已经搭建了C++的编程框架,虽然不是所有C++特性都支持了,比如new和delete,以及虚析构函数等,但是用来移植GuiLite已经足够了。下面就开始着手这一工作。

1 代码选择

GuiLite的例子比较丰富,从控件到动画、甚至3D的实现,都可以找到。浏览了一圈后,我选择从HelloTimer开始动手。

这是在STM32F103上运行的代码:

图1 STM32F103例程: HelloTimer
继续阅读“UEFI开发探索47 – UEFI上移植GUILite”

2,743 total views, no views today

UEFI开发探索46 – UEFI支持C++

请保留-> 【原文:  https://blog.csdn.net/luobing4365http://yiiyee.cn/blog/author/luobing/】

由于GUILite是由C++开发的,将其移植到UEFI下,意味着代码必须用C++来编写。

以下的内容,大部分来自于《UEFI原理与编程》第10章,将需要的代码整合到了我自己的框架中。有些书中没有遇到的小问题,博客中也给了解决办法。

1 C与C++之于UEFI

UEFI中的程序遵循的是C语言的规则,大部分时候应该用模块化的思维方式去理解代码。在日常开发的时候并没有什么问题,何况C语言比C++更适合直接与硬件打交道的场景。不过,遇到稍大点的GUI应用,或者移植遗留的C++代码时,就不得不采用C++了。比如这次的GuiLite的移植工作。

在windows下,开发所用的工具是Visual Studio,编译器cl本身就是支持C++的。因此,我们所要做的工作是让UEFI的入口函数能够“认识”C++的代码。

C++与C的主要区别在于函数名、数组名等,在经过编译后会不同。这是名字修饰的过程,大部分编译原理的书籍中都有描述过。因此,如果直接用C的代码去调用C++的库,会导致链接失败的。

为了支持C++,EDK2在后续的版本中,也逐渐地添加了一些支持。比如在生成的中间文件AutoGen.h中,自动添加了extern “C”,解决了中间文件的名字修饰问题。

我的开发环境是UDK2018+VS2015,在Win10上进行开发的。

2 支持基础的类

基本上进行以下四个步骤,就可以支持C++的类的功能了。

1) 解决名字修饰问题

这个问题比较简单,只需要在C++源文件中,将C语言的头文件用extern “C”包含起来就可以了。如图:

图1 c与C++的名字修饰问题
继续阅读“UEFI开发探索46 – UEFI支持C++”

3,569 total views, no views today

UEFI开发探索45 – GuiLite概览

请保留-> 【原文:  https://blog.csdn.net/luobing4365http://yiiyee.cn/blog/author/luobing/】

在开始这个探索系列的时候,我就计划在UEFI上移植一个完整的GUI库。

前面开发各种图形编程、特效实现的代码,其实有很大一部分来自于我之前另外一个项目-Foxdisk。在这个项目中,某种程度上实现了任务的切换,可以看做一个小型的、带有图形显示的shell界面。

不过,Foxdisk中的键盘处理是完全脱离于图形的,而且也没有实现鼠标的处理。简而言之,这是一个很松散的、模块化的GUI库。与我期望的,类似于MFC、QT、JUCE之类的库相差甚远。

UEFI不是一个完整的操作系统,所选用的GUI库实际上最好偏向于嵌入式的。在简单考察了几个开源的GUI库后,包括LearingGUi、GuiLite、littlevgl等,我选择了从GuiLite开始着手这项工作。

一方面是因为其代码量看起来不大,6000行左右,花费的时间应该不会太多;二是这款开源库是国人开发的,我也加入了作者建的QQ群,有什么问题可以很方便地请教。

1 GUILite类的组织

按照其文档介绍,GuiLite只做两个工作:界面元素管理和图形绘制。而图形绘制不依赖于界面管理,可以独立存在,以应对需要移植到资源有限的单片机环境。

其类的组织图如下:

图1 GUILite类图
继续阅读“UEFI开发探索45 – GuiLite概览”

4,062 total views, no views today

Foxdisk12 – 图形显示1

请保留-> 【原文: http://yiiyee.cn/blog/author/luobing/】

最近在写UEFI博客的时候,遇到些阻碍。我想移植一款开源的GUI到UEFI下,目前还没有找到。不过,博客开天窗这么久,总是不像话,所以回来继续写Foxdisk的博客了。

Foxdisk的博客更新较慢,主要是觉得这些都是Legacy BIOS下的东西,可能想了解的人不多,我也是随性而写,并不制定计划。

使用Foxdisk3的代码,很难演示如何进行图形编程。因此,我还是使用平常调试用的程序框架来说明。所有的代码,都是在DOS下实验通过,然后再移植到Foxdisk3的代码中去的。

特别说明,Foxdisk3只针对Legacy BIOS,所有访问硬盘、图形显示、键盘访问以及时钟中断的构建,都是在Legacy BIOS的架构下进行的。如想了解UEFI BIOS下如何编写类似代码,请移步我的另一博客-《UFEI开发探索系列》

1 编译和运行环境

我以前都是在虚拟机下调试,使用的是VirtualPC2.5以及Bochs,偶尔也用过Virtual BOX和Vmware构建。每种环境都各有优缺点,比如Bochs的调试环境非常完备,不过显示的时候颜色有时候会很奇怪。

如果只是演示图形编程的话,我觉得DosBox比较好:启动快、DOS环境模拟得很好。我使用的是DosBox v0.74-2,到网上去找即可,免费的。

图1 DosBOX
继续阅读“Foxdisk12 – 图形显示1”

3,291 total views, no views today

UEFI开发探索44 – 龙芯下的UEFI App和Option ROM

请保留-> 【原文:  https://blog.csdn.net/luobing4365http://yiiyee.cn/blog/author/luobing/】

年初的时候,不少客户都在问,国产的电脑上是不是能用隔离方案?

工程师做了一番调查,大部分客户用的都是龙芯的电脑(3A3000)。硬件上来说,主要是看PCI/PCIE的支持情况;软件上,BIOS需要支持我们的Option ROM,操作系统上的应用程序也得重写。

总的来说,工作量不算大,也不算小,由此开始了我们几个月的产品适配过程。

图1 调试用的机器
继续阅读“UEFI开发探索44 – 龙芯下的UEFI App和Option ROM”

5,932 total views, no views today

UEFI开发探索 – 间幕

嗯,最近把博客移动到了CSDN上了,主要是那边比较方便查看博客:十几篇文章的标题可以在一个页面上显示。

我们的博客网站就没那么方便啦,还是比较适合个人浏览。我们俩也没那么多时间去调整,就这么继续写下去吧。

预计中的50篇,马上就要接近尾声了。我正在搜肠刮肚地寻找课题,可是感觉每个课题都特别大,比如写个uefi下的磁盘管理工具、写个类似grub的多引导工具、移植个GUI库过来等等。

都很有趣,也都很…费时间。

中年程序员大叔的时间可是很宝贵的,能压缩的时间只剩下睡觉了。再这么下去,仿佛去世多年的爷爷在河的那边正向我招手呢,模模糊糊的能看见…

总之,有兴趣的话,可以去CSDN上关注下:

https://me.csdn.net/luobing4365

当然,这里一直都会是我的主战场,不定期地更新自己的技术点滴或者感想。

最后,上一张老家的风景图。国庆的时候带娃去明月山了,温泉泡得很舒服,爬山很好玩。明月山和羊狮慕的栈道,挂在山腰,走完要两个多小时,非常有意思。

当然,不愧是AAAAA级景区,价格也不便宜,虽然大部分都是老哥付的钱^^

1,913 total views, no views today

UEFI开发探索43 – Protocol的使用2

请保留-> 【原文:  https://blog.csdn.net/luobing4365http://yiiyee.cn/blog/author/luobing/】

今天来探索上次提出的第三个问题:如何产生Protocol?

在常看的书《UEFI原理与编程》中,实际上已经介绍了如何开发UEFI服务了。他以视频解码为例,提供了一个完整的解码库。

目前对视频解码没有什么兴趣,因此,这篇内容对我来说,多余的枝节太多了。我准备构建一个比较简单的框架型代码,可以用来在屏幕上画几何图形,以熟悉如何开发Protocol。

1 UEFI Driver

相比于Windows driver,UEFI driver简单很多,大致可以分为两类:符合UEFI驱动模型的驱动和不遵循UEFI驱动模型的驱动,如图:

图1 UEFI Images – EDKII Driver Writer’s Guide section3.7
继续阅读“UEFI开发探索43 – Protocol的使用2”

8,143 total views, no views today

UEFI开发探索42 – Protocol的使用1

请保留-> 【原文:  https://blog.csdn.net/luobing4365http://yiiyee.cn/blog/author/luobing/】

虽然一直使用各种Protocol来实现需要的程序功能,但对其背后的原理、实现方法,一直都比较模糊。我奉行的是“先用再说”的实用主义,正好周末有点闲暇,探究一下对Protocol理解模糊的地方。

图1 Protocol的构成

如图为Protocol的结构图,摘自于UEFI Spec 2.8 page 45。

我想弄清楚的问题如下:

1) 如何使用Protocol服务?
2) Protocol这种机制在UEFI中是如何实现的?
3) 如何实现一个Protocol?

继续阅读“UEFI开发探索42 – Protocol的使用1”

6,670 total views, no views today