UEFI学习笔记

高通平台UEFI学习笔记



前言

作为一个嵌入式软件开发工程师,如果不懂UEFI实在说不过去,因此决定接下来一段时间把这块骨头啃了。


一、UEFI概述

UEFI是一种规范,定义了操作系统与平台固件之间衔接的软件接口。

UEFI启动流程

按照调用栈的形式,UEFI有如下几个启动阶段

//安全启动阶段,主要以汇编代码为主
SEC
	//EFI前期初始化
	//加载PEIM模块,主要包括CPU初始化,芯片初始化,主板初始化
	PEI
		//驱动执行环境
		//遍历固件中所有的Driver,执行所有的Driver,主要包括设备、总线、驱动与服务
		//通常我们的UEFI开发工作,也就是在这一阶段执行
		DXE
			//加载启动项
			BDS
				//交接系统控制权权给操作系统加载器
				TSL
					//这一阶段UEFI只剩下run time service,大部分控制权被操作系统接管
					RT
						//操作系统挂了,就有可能进入这一阶段,用于灾难恢复
						AL

Module与Package基本概念

UEFI根目录下,会有很多以*Pkg命名的文件夹。通常会以这样一个文件夹作为一个PackagePackage的一般目录形式如下

Package/
	declaration.dec
	description.dsc
	flashDescriptionFiles.fdf
	Module/
		source.c
		head.h
		information.inf

.inf文件类似于makefile, 描述了要编译的源文件
.dsc文件,描述了要添加的.inf文件
.dec文件,作为声明文件,可以供其他的模块使用。

使用build命令编译一个Package,可以生成*.efi文件
使用GenFW命令,可以制作Rom Image

值得注意的是,不管是哪个阶段的驱动或者应用,都是使用上面的目录结构进行编写的。只不过在模块的.inf文件中,需要在MODULE_TYPE字段中,指明这是一个什么模块

组成

在高通平台下,UEFI由两部分组成:

  1. XBL Core,包含与芯片相关的protocols, drivers, applications. 比如charging应用. XBL的代码位于non-HLOS boot_images
  2. ABL,包含与芯片无关的applications, 比如fastboot. ABL是Android开源代码树的一部分。ABL的代码位于Android boottable bootloader.

二、Handle&Protocol模型

1.总线、设备、驱动模型

在linux操作系统中,采用了总线、设备、驱动模型,设备挂载在总线上。
总线遍历每一个设备时,会遍历所有已安装的驱动,如果设备与驱动匹配,则进行驱动程序的运行。
系统安装驱动时,会遍历总线上所有的已存在的设备,如果驱动与设备匹配,则进行驱动程序的运行。

2.Protocol

在UEFI中,Protocol是一种与UEFI驱动通信的接口,每一个Protocol都有一个唯一的GUID编号,每一个协议使用一个struct结构体表示,其中成员函数(c语言的函数指针)表明了协议拥有的方法。

在UEFI使用handle表示一个设备的Control,熟悉linux开发环境的同学应该很容易理解,通过这个handle就可以操作具体的设备。

Protocol的经典使用流程如下:

/* 根据protocol GUID找到所有使用该协议的handle */
gBS->LocateHandleBuffer();

/* 对于某一个handle,获取该handle的protocol实例 */
gBS->OpenProtocol();

/* 和上面的函数一样,不过是一个简化了某些常用入参的函数封装,底层也是OpenProtocol */
gBS->HandleProtocol();

/* 通过获取到的protocol实例,调用protocol中的方法,与设备通信 */
protocol->method();

可以将protocol看作UEFI中的系统调用。

UEFI驱动

UEFI中的驱动和linux不太一样,它并没有抽象为一个具体的数据结构。
通常,编写一个设备驱动需要实现三部分。

  1. EFI_DRIVER_BINDING_PROTOCOL,这是一个UEFI内置的结构体,我们需要实现它的supported, start, stop函数。在模块入口函数中,把这个数据结构进行注册,系统就可以使用这一个Protocol了。
  2. EFI_COMPONENT_NAME_PROTOCOL,这也是一个UEFI内置的结构体,与EFI_DRIVER_BINDING_PROTOCOL在模块入口函数中同时注册。这样系统就可以使用获取设备名称的Protocol了。
  3. EFI_DRIVER_BINDING_PROTOCOL的start函数中,实现私有的Protocol的注册,这个Protocol是我们自定义的驱动内容,具体驱动自定义功能就在这里实现。

可以这样认为,一个UEFI驱动,至少包含以上三个protocol。当然也可以提供更多的protocol,所以说驱动是一个抽象概念,在UEFI中并没有实际的数据结构。

UEFI驱动与服务型驱动的对比。

  1. 服务型驱动直接在Image入口函数中注册,长期存在于内存当中,只有当模块卸载之后,才会将驱动卸载。
  2. UEFI驱动则是在Image入口函数中先注册一个EFI_DRIVER_BINDING_PROTOCOL。在它的start函数中进行具体Protocol的注册,这个注册其实就是一个服务型驱动。同时在EFI_DRIVER_BINDING_PROTOCOL的supported与stop中提供了支持与卸载功能。因此,从代码的角度来看,服务型驱动实际上是UEFI驱动的一部分。

三、系统表

在linux系统中,用户空间通过系统调用来使用内核空间提供的系统服务。
在UEFI中,UEFI应用程序则通过系统表来使用内核空间提供的服务。
上面用到的gBS就是启动服务表。另外一张系统表则是运行时服务表。

系统表的使用

系统表是在DXE阶段被初始化的,因此在这个阶段之后才能够使用。

在模块入口函数,可以使用入口函数的入参SystemTable访问系统表,入参ImageHandle则可以访问系统固件镜像。在其他函数中,则可以使用gST, gBS, 来访问系统表,gImageHandle则可以访问ImageHandle,这是通过镜像构造函数来赋值实现的。

UEFI中,由于所有程序都运行在RING0优先级,因此用户空间和内核空间,实际上是一个地址空间,可以通过指针地址直接访问。

四、操作系统加载器

通常,每个UEFI系统至少有一个ESP(EFI System Partition)分区,在这个分区上,存放了启动文件。

UEFI不仅具有读写硬盘的能力,同时也具有读写文件的能力。

操作系统加载器是以文件的形式存放在ESP分区内。


总结

UEFI其实有点像单片机编程,但是UEFI将整个系统执行过程分为了固定的几个阶段,用户自定义的需要,则需要根据实际情况放在固定的阶段中。在单片机编程中,也可以仿照这种编程风格来作为系统框架。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
UEFI Shell是一种全新的操作系统环境,在现代计算机上广泛使用。相较于BIOS,UEFI Shell在启动时间和性能方面都有着很大的优势。UEFI Shell有其独特的运行环境,为用户提供了一种类似于操作系统的命令行界面来控制计算机的硬件和软件。 UEFI Shell可以很好的应用于系统调试和维护工作。因为UEFI Shell能够与UEFI BIOS直接进行交互,可以读取和修改UEFI BIOS中的各种变量。这些变量包括了计算机的系统时间、启动磁盘分区信息、设备启用状态等等。所以,当系统出现问题时,可以通过UEFI Shell来获取更多的系统信息、检测硬件故障以及查找系统错误等。 同时,UEFI Shell也支持各种文件系统格式。这使得我们可以在UEFI Shell中查看和管理硬盘分区,从而进行数据备份与还原、系统安装和修复等操作。此外,UEFI Shell还支持各种基本的命令,如文件与目录操作、网络连接管理、进程控制等。这让我们可以在更高效的状态下调试和管理系统。 对于初学者来说,UEFI Shell学习并不是一件容易的事情。因为UEFI Shell的命令和语法都有一定的学习曲线,需要一定的时间和经验去掌握。但是,如果您熟练掌握了UEFI Shell的使用,不仅可以解决常见的操作问题,还可以探究计算机系统的底层运作机理。这对于系统工程师来说尤为重要。 总之,UEFI Shell作为一种新兴的操作系统环境,拥有着广泛的应用场景和巨大的优势,不管是对于初学者还是经验丰富的系统工程师来说,掌握UEFI Shell的各种技术是一个不可或缺的技能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值