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环境”

574 total views, 2 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”

436 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++”

436 total views, 2 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概览”

615 total views, 1 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”

1,621 total views, no views today

Zephyr系统快评

请保留:【作者:张佩】 【原文:www.yiiyee.cn/blog】

Zephry是Linux基金会托管的一个嵌入式RTOS系统,主导开发的是Intel。我对这个系统进行了学习之后,得到了下面的5条总体认识。

  1. Zephyr的内核模式是宏内核,不是微内核;设备驱动都被集成在内核中;内核编译采用Kconfig脚本配置,资源配置也通过它在编译时指定
  2. Zephyr支持的平台:arm、x86、RISC-v、ARC、NIOS 2、POSIX等
  3. ARM平台支持不完全:只支持arm 32系列的m/r平台,a平台不支持;同时,也不支持arm64
  4. Zephyr支持100多种嵌入式开发平台,嵌入式友好;内核size可以小至8kB
  5. Zephyr只有mpu(内存保护单元)的支持,任务之间的内存是相互隔离的,但不支持虚拟内存;多个用户应用同时运行有一定的困难,目前仅支持单应用的形式

内核实现

Zephyr采用的是标准的宏内核的架构,这对于它面向MCU进行开发是有利的。如果采用微内核的话,需要有稳健的IPC机制,不仅执行效率上有所降低,并且需要更多的代码量。

继续阅读“Zephyr系统快评”

1,054 total views, 7 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”

1,195 total views, 4 views today

UEFI开发探索 – 间幕

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

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

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

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

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

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

https://me.csdn.net/luobing4365

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

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

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

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

963 total views, 6 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”

919 total views, 4 views today

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

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

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

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

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

1 支持的服务函数

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

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

1,527 total views, 5 views today

鸿蒙OS速览

请保留 -> 【作者:张佩】【原文:www.yiiyee.cn/blog

鸿蒙在HDC 2019上作为最重要的产品被隆重推出,现在已经为世人所知。它的三个重要特点是:

第一,它基于微内核的实现,可以很好地运行于IoT及安全相关的嵌入式场景中;

第二,它是分布式架构,使得它可以很好地运行于多端协作的场景;

第三,它面向的是全场景的应用,囊括了像智能穿戴这样的IoT设备、智慧大屏、智能终端以及PC机等。其中荣耀大屏(电视)是它第一个产品。

鸿蒙OS主要特性速览和解析

preview
继续阅读“鸿蒙OS速览”

803 total views, 1 views today

Little Kernel 代码走读(二)

作者:张佩】【原始链接:www.yiiyee.cn/blog

任务管理

LK支持多任务,并且也支持多核。多任务和调度,是LK内核最复杂的功能。一般的嵌入是系统,为了实现简单和便利部署的考虑,会把多任务实现得比较简单,比如uos这样的rtos系统便是了。但LK其实有比较丰富而全面的多任务支持的基础。这使得一些功能更全面的微内核系统比如Zircon,会选择基于它进行开发。

线程结构体

每个内核实现都会为线程创建一个结构体,用来管理任务的执行和维护线程状态。由于无受限的多任务支持能力,所以系统中的线程数量和功能,是不受限的。所以要有一种管理设施,能够对所有的任务进行无区别的管理(某些时候是有区别的,比如idle线程、init线程等,但很少)。这个模块就是内核的任务管理器。而它管理这些任务的抓手,就是线程结构体。

下面是LK定义的线程结构体:

继续阅读“Little Kernel 代码走读(二)”

1,105 total views, 6 views today

Little Kernel 代码走读(一)

作者:张佩】【原始链接www.yiiyee.cn/blog

Little Kernel是一个微型内核,某种意义上,可以被定义为微内核。当下声势大张的谷歌Fuchsia OS的微内核系统就是从它演进而来的。它更为一般的作用,是在安卓设备中,作为一个典型的boot loader并启动安卓OS。相较于更通用的arm平台上的u-boot,它当然更加地简单。所以如果不需要boot loader中实现复杂的功能,特别是不需要驱动复杂的IO设备的话,little kernel是非常合适的。

当然,并不是说Little Kernel(简称LK)没有IO支持。它对于基本的IO设备还是有接口层面的支持的。比如串口、GPIO、基于frame buffer的图形显示设备,以及更高级的设备比如磁盘设备、USB、网络等,甚至virtio设备。但仅限于接口定义,却缺少具体的设备支持。所以新平台的设备驱动开发是一个巨大任务。

在这个文档中,我带领大家一起走读一下LK的核心代码。

LK内核代码走读

这部分我带领大家走读一下LK内核部分的代码。因为代码很简单,所以走读一遍并不费事。和Linux内核相比,走读LK的内核如同在电视上看别人爬山一样,所费精力与实际爬山之人,实有天壤之别。但如鲁迅说的,我的双脚虽不能如愿地周游世界,但通过眼睛却能部分地实现它,观看风光纪录片便如部分地身临其境地领略了那些风光,也能增广见闻的。所以LK虽微,分析它亦不费事,但学习它也能达到增广见闻的目的,部分地达到学习内核实现的目的。

LK官方有一篇和小的文档介绍内核API,然太简。参考。下面我带领大家分别地看一下LK的内存管理、任务管理和同步机制,这三个主要部分的实现逻辑。

继续阅读“Little Kernel 代码走读(一)”

1,687 total views, 3 views today

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

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

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

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

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

1 编译框架

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

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

1,073 total views, 2 views today

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

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

准确地说,应该是在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调试环境”

1,116 total views, 5 views today