高通平台UEFI有关介绍
高通平台UEFI有关介绍
背景
我需要在高通平台上学习点亮LCD,目前通过同事在别的平台的配置代码,我已经将kernel部分的屏幕点亮了;剩余的工作量就在BP侧,也就是系统刚开机的那一段时间。在开发过程中,我发现我对BP侧的开发有点不太熟悉,因此我需要搞清楚有关的概念。只有搞清楚了这些基本概念,我才能够在后续的工作中不留下隐患。
有关文档:
- https://www.cnblogs.com/we-hjb/p/9800627.html
- https://blog.csdn.net/u014089131/article/details/73617716
- https://blog.csdn.net/weixin_41803132/article/details/107692862
- 高通UEFI、XBL及ABL的详细介绍: 《80_P2484_37_LINUX_ANDROID_UEFI_OVERVIEW.pdf》。
UEFI 介绍
UEFI(Unified extensible firmware interface)统一的可扩展固件接口,是一种详细描述类型接口的标准。
可扩展固件接口(Extensible Firmware Interface,EFI)是 Intel 为 PC 固件的体系结构、接口和服务提出的建议标准。其主要目的是为了提供一组在 OS 加载之前(启动前)在所有平台上一致的、正确指定的启动服务,被看做是有近20多年历史的 BIOS 的继任者。
BIOS是汇编实现的,采用的是16bit 实模式寻址方式,最大支持的内存只有1M,代码易读性以及实现的功能都受到限制,而且移植起来不方便。BIOS支持的最大磁盘空间不超过2TB。
UEFI克服了上述的所有缺点,采用C语言实现,分层,模块化设计,实现了CPU以及驱动的无关性。UEFI可以理解为一个完整的系统,包含了上电时序,驱动实现,os环境建立(这个os可以理解为UEFI运行独有的os,非linux,windows),应用程序。其中应用程序支持网络配置,类shell环境,fastboot,linux loader等。
UEFI启动阶段
UEFI从上电到关机,一共有七个阶段:
- SEC(安全验证)
其功能包括:接受处理系统启动与重启信号、初始化临时RAM区、作为可信系统的根、以及传递系统参数到下一阶段。
其执行流程是:
上电 -> ResetVector -> SEC函数入口 -> PEI函数入口 - PEI
主要功能是为DXE准备执行环境,将HOB列表传递给DXE。此阶段到后期内存才被初始化,所以资源相当有限,尚未可进行复杂的工作。 - DXE
此阶段执行大部分系统初始化工作,内存已被初始化,可以进行大量复杂工作。当所有的Driver都执行完毕,说明系统初始化完成,接着通过EFI_BDS_ARCH_PROTOCAL找到BDS并调用BDS的入口函数,进入BDS阶段。 - BDS
此阶段主要功能是执行启动策略,等OS Loader启动后,系统进入TSL阶段。 - TSL
TSL是OS Loader执行的第一阶段,OS Loader在这个阶段作为UEFI APPLICATION运行,当ExitBootServices服务被调用后,进入RT(RunTime)阶段。 - RT
系统进入此阶段后,系统控制权从UEFI内核转交到OS Loader上。随着OS Loader的执行,OS最终取得对系统的 控制权。 - AL
在RT阶段,如果系统遇到灾难性错误,系统固件需要提供错误处理和灾难恢复机制,而这种机制运行在AL阶段。
其中UEFI中涉及的名词缩写 :
缩写 | 意义 |
---|---|
UEFI | Unified extensible firmware interface |
SEC | Security |
PEI | Pre EFI initialization |
DXE | Driver execution Environment |
BDS | Boot Dev Select |
TSL | Transient System Loa |
RT | Runtime |
AL | After life |
GUID | Globally Unique Identifier |
CSM | Compatibility Support Modul |
TCG | Trusted Computing Group |
PE | Portable executable |
COFF | Common object file format |
FV | Firmware Volume |
UEFI有关文件格式
fdf:flash definitionfile,描述flash分区地址范围
dec:package declarationfile,定义了不同模块的GUID信息
dsc:description file,主要包含需要用到的所有inf文件
inf:单个模块的编译信息,类似makefile
efi :最终编译生成的UEFI可执行文件
高通平台的UEFI设计
高通在MSM8998上引入了UEFI,用来代替LK(Little Kernel)。
而高通UEFI由XBL和ABL两部分组成。
在新版本中,之前属于LK的设备驱动都放在了XBL核心,Linux加载启动及fastboot等功能组件则作为独立的UEFI应用存在。
XBL
XBL负责芯片驱动及充电等核心应用功能。
XBL核心是none-HLOS boot_image
代码的一部分,属于高通私有代码。
代码路径为:BP侧的BOOT.XX/boot_images
tree -L 2
.
├── about.html
├── ADSP.VT.5.4.1
│ ├── adsp_proc
│ ├── BuildProducts.txt
│ └── HY11_1.txt
├── Agatti.LA.1.0.1
│ ├── common
│ └── contents.xml
├── BOOT.XF.4.1
│ ├── BOOT.XF.4.1-00200-KAMORTALAZ-1.brfx
│ ├── BOOT.XF.4.1-00200-KAMORTALAZ-1_notes.txt
│ ├── boot_images ▲
│ │ ├── ArmPkg
│ │ ├── ArmPlatformPkg
│ │ ├── BaseTools
│ │ ├── Build
│ │ ├── Conf
│ │ ├── EmbeddedPkg
│ │ ├── FatPkg
│ │ ├── IntelFrameworkModulePkg
│ │ ├── IntelFrameworkPkg
│ │ ├── MdeModulePkg
│ │ ├── MdePkg
│ │ ├── NetworkPkg
│ │ ├── OptionRomPkg
│ │ ├── QcomPkg
│ │ └── ShellPkg
│ ├── BuildProducts.txt
│ ├── copyrightmod.xml
│ ├── CRM_BOOT.XF.4.1-00200-KAMORTALAZ-1.cs
│ ├── si
│ └── VerifySrc.log
├── BTFM.CHE.2.1.5
│ └── btfm_proc
├── BTFM.CMC.1.2.0
│ └── btfm_proc
├── build_sdm6115.bat
├── CDSP.VT.2.4.1
│ ├── BuildProducts.txt
│ ├── cdsp_proc
│ └── HY11_1.txt
├── env.bat
├── Kamorta.LA.1.0.1
│ ├── common
│ └── contents.xml
├── LA.QSSI.11.0
│ └── LINUX
├── LA.UM.9.15
│ └── LINUX
├── MPSS.HA.1.0
│ └── modem_proc
├── RPM.BF.1.10
│ └── rpm_proc
├── TZ.APPS.1.1
│ └── qtee_tas
├── TZ.APPS.2.0
│ └── qtee_tas
├── TZ.XF.5.1
│ └── trustzone_images
├── VIDEO.VE.6.0
│ ├── manifest.xml
│ └── venus_proc
└── WLAN.HL.3.2.4
└── wlan_proc
UEFI代码中大量使用了protocol概念,这个protocol其实指的是驱动,包含了驱动函数指针和数据。我们会在附录中介绍这一部分。
总之,记住:XBL实现的protocol,在ABL中可以直接调用。
ABL
ABL包括芯片无关的应用如fastboot
。ABL则在开源Linux Android代码树里。
ABL的编译非常简单,依次执行命令:
source build/envsetup.sh
lunch 32
make aboot
不同的厂商对UEFI有不同的实现,一种比较常用的开源实现是EDK2;EDK2是一个遵循UEFI标准和PI标准的跨平台固件开发环境,EDK2支持多种操作系统, 也支持跨平台编译。
确切来讲,高通所使用的edk2编译以后就是做为ABL部分的代码,同XBL一同构成了UEFI。
高通UEFI有关源码
对于高通平台启动过程依次为:PBL
->XBL
->ABL
。
一般用户定制化主要集中在ABL中,这部分代码树如下:
这部分里面主要是作为linux-loader 用来加载linux,以及fastboot。
用户修改主要集中在这两个部分,入口函数LinuxLoaderEntry。
${Andrioid源码树}/bootable/bootloader/edk2/QcomModulePkg
├── Application
│ └── LinuxLoader
│ ├── LinuxLoader.c
│ └── LinuxLoader.inf
├── Include
│ ├── Library
│ │ ├──BoardCustom.h
│ │ ├── Board.h
│ │ ├──BootImage.h
│ │ ├──BootLinux.h
│ │ ├──BootStats.h
│ │ ├──Decompress.h
│ │ ├──DeviceInfo.h
│ │ ├── DrawUI.h
│ │ ├──FastbootMenu.h
│ │ ├── Fonts.h
│ │ ├── KeyPad.h
│ │ ├──LinuxLoaderLib.h
│ │ ├── list.h
│ │ ├──LocateDeviceTree.h
│ │ ├──MenuKeysDetection.h
│ │ ├──PartitionTableUpdate.h
│ │ ├── Recovery.h
│ │ ├── Reg.h
│ │ ├──ShutdownServices.h
│ │ ├──StackCanary.h
│ │ ├──UnlockMenu.h
│ │ ├──UpdateCmdLine.h
│ │ ├──UpdateDeviceTree.h
│ │ └──VerifiedBootMenu.h
│ └── Protocol
│ ├── EFICardInfo.h
│ ├── EFIChargerEx.h
│ ├── EFIChipInfo.h
│ ├── EFIChipInfoTypes.h
│ ├── EFIEraseBlock.h
│ ├── EFILimits.h
│ ├── EFIMdtp.h
│ ├── EFIPlatformInfo.h
│ ├── EFIPlatformInfoTypes.h
│ ├── EFIPmicPon.h
│ ├── EFIPmicVersion.h
│ ├── EFIQseecom.h
│ ├── EFIRamPartition.h
│ ├── EFIResetReason.h
│ ├── EFIRng.h
│ ├── EFIScmModeSwitch.h
│ ├── EFIUsbDevice.h
│ ├── EFIUsbEx.h
│ ├── EFIVerifiedBoot.h
│ └── UsbEx.h
├── Library
│ ├── BootLib
│ │ ├── Board.c
│ │ ├──BootLib.inf
│ │ ├──BootLinux.c
│ │ ├──BootStats.c
│ │ ├──Decompress.c
│ │ ├──DeviceInfo.c
│ │ ├── DrawUI.c
│ │ ├──FastbootMenu.c
│ │ ├── KeyPad.c
│ │ ├──LinuxLoaderLib.c
│ │ ├──LocateDeviceTree.c
│ │ ├──MenuKeysDetection.c
│ │ ├──PartitionTableUpdate.c
│ │ ├── Recovery.c
│ │ ├──ShutdownServices.c
│ │ ├──UnlockMenu.c
│ │ ├──UpdateCmdLine.c
│ │ ├──UpdateDeviceTree.c
│ │ └──VerifiedBootMenu.c
│ ├── FastbootLib
│ │ ├──FastbootCmds.c
│ │ ├──FastbootCmds.h
│ │ ├──FastbootLib.inf
│ │ ├──FastbootMain.c
│ │ ├──FastbootMain.h
│ │ ├──MetaFormat.h
│ │ ├──SparseFormat.h
│ │ ├──UsbDescriptors.c
│ │ └──UsbDescriptors.h
│ ├── StackCanary
│ │ ├──StackCanary.c
│ │ └──StackCanary.inf
│ └── zlib
│ ├── adler32.c
│ ├── inffast.c
│ ├── inffast.h
│ ├── inffixed.h
│ ├── inflate.c
│ ├── inflate.h
│ ├── inftrees.c
│ ├── inftrees.h
│ ├── zconf.h
│ ├── zlib.h
│ ├── zlib.inf
│ ├── zutil.c
│ └── zutil.h
├──QcomModulePkg.dec
├──QcomModulePkg.dsc
├──QcomModulePkg.fdf
└── Tools
├── app_path_set.cmm
├── check_paths.cmm
├── debug_app.cmm
├── elf_tools.py
├── image_header.py
├── load_uefi_dump.cmm
├── log_save.cmm
├── symbol_Load.cmm
└── uefi_core_path_set.cmm
附录:为什么android 默认bootloader选择lk?
reference:https://blog.csdn.net/leo_wdls/article/details/45173643
结论:用于移动通信的android设备(如手机平板):软件小巧,架构简单,满足android bootloader的基本需求。
lk源码目录位置:
bootable/bootloader/lk
Android bootloader需求:
加载引导
linux kernel
需要驱动
Display
、Usb
、Keypad
、Pmic
、Vibrator
Uboot 的特点:
加载引导linux kernel
发展早,软件成熟稳定,功能完备;
支持的多个CPU 体系
支持复杂驱动,如Fs/Network等等;
Little Kernel特点:
加载引导linux kernel
轻量级、不支持复杂的驱动
附录:关于UEFI的Protocol概念
为什么要有Protocol?
大家都知道,UEFI的英文翻译过来应该叫“可扩展固件接口”。这个名词中最重要的事实上是“可扩展”这三个字。换言之,相比传统的系统固件而言,UEFI固件具备了完善的可扩展支持。这个概念对软件行业不是一个新概念,但是对bios这样一个陈旧腐朽的东西而言,的确是一个创新的思想。
所谓可扩展的含义就是可以在系统完成后(编译为binary)之后,再次为系统增加新的功能,而不用重新rebuild整个系统。在这个大的需求的前提下,还有一些其他的重要的含义,比如必须支持不同的组件的独立开发。
比如A厂商今天针对某硬件开发了一个驱动,他们发布了一个二进制包APackage;而B厂商则针对另一个硬件开发了一个驱动,他们发布了一个二进制包BPackage;现在APackage和BPackage都需要集成到bios内。且必须以二进制的形式集成。因为A和B厂商的知识产权需要得到尊重。或者像OS下那样,可以通过某种方法在系统已经运行起来后加载到内存。
更好玩的是,A厂商并不希望自己需要重新从车轮开始发明。比如他们针对的硬件是一个PCI的适配器,他们希望希望系统里已经有了诸如ReadPci()或者WritePci()这样调用来简化他们编程上的工作。换言之,他们希望目标系统能够支持不同的二进制组件之间的运行时通讯。
支持二进制组件的运行时通讯是一个十分复杂的技术。这里所谓的通讯,包括但不限于如下的含义:
1、互操作。A组件自由可以调用B组件实现的函数。反过来也一样。
2、数据传递。双方可以通过某种方法(shared memory, pipes and etc)互相交换数据。
3、可探测。某组件必须具备探测另一个组件是否存在的能力。
4、组件的开发必须是独立的。开发A组件不需要B组件的源代码,反之亦然。
这可以说是现代操作系统的一个核心概念。
熟悉Windows的朋友可能十分清楚Windows下的COM组件,所有的COM组件都可以互相通讯的。且应用程序可以自由的使用任何一个组件提供的服务。
只有具备了这样的能力的系统才可以被叫做“可扩展”的。而UEFI为了达到可扩展的能力,必须提供一种机制来提供支持,于是UEFI领域的专家们发明了Protocol。
从约定到接口
Protocol从本质上说是一种调用者与被调用者之间的“约定”。而这种“约定”在软件开发领域有另一个更形象化的名字叫接口(Interface)。
为了做到二进制间的互操作,那么参与操作的双方(调用者与被调用者)都必须做出一定的让步,这个让步就是双方必须遵循实现商量好的调用方法(接口)。而这种事先的约定的接口就是protocol的定义。而这种定义尤以.h文件的形式加以实现。
由于目前UEFI还是几乎是用C语言开发,基本上不存在跨语言的问题,所以Protocol才可以表达成.h
文件。
而Windows下的COM的Interface,由于考虑到跨语言的问题,才专门有了一个新的通用语言叫接口定义语言(IDL,Interface Definiton Language),使用时候专门有一个IDL的compiler将IDL翻译成各个其他语言专用的表达方法(对于C语言,就是生成对应的.h文件)。
具体实现
定义
我们现在来看一个.h文件,看看一个protocol到底是怎样定义出来的。
用任意一个编辑器打开一个.h
的接口文件,无论是什么样的接口,都必定是遵循UEFI规范所定义的标准而实现的。
以rampatition为例:boot_images/QcomPkg/Include/Protocol/EFIRamPartition.h
中声明了rampatition protocol
:
/**
@file EFIRamPartition.h
@brief RamPartition EFI protocol interface.
*/
/*=============================================================================
Copyright (c) 2015,2018 Qualcomm Technologies, Incorporated.
All rights reserved.
Qualcomm Technologies, Confidential and Proprietary.
=============================================================================*/
/*=============================================================================
EDIT HISTORY
when who what, where, why
-------- --- -----------------------------------------------------------
06/05/18 daisond Added GetMinPasrSize module in rampartition protocol
09/30/15 vk Initial Revision
=============================================================================*/
#ifndef __EFIRAMPARTITION_H__
#define __EFIRAMPARTITION_H__
/** @cond */
typedef struct _EFI_RAMPARTITION_PROTOCOL EFI_RAMPARTITION_PROTOCOL;
/** @endcond */
/** @addtogroup efi_ramPartition_constants
@{ */
/**
Protocol version.
*/
#define EFI_RAMPARTITION_PROTOCOL_REVISION 0x0000000000010001
/** @} */ /* end_addtogroup efi_ramPartition_constants */
/* Protocol GUID definition */
/** @ingroup efi_ramPartition_protocol */
#define EFI_RAMPARTITION_PROTOCOL_GUID \
{ 0x5172FFB5, 0x4253, 0x7D51, { 0xC6, 0x41, 0xA7, 0x01, 0xF9, 0x73, 0x10, 0x3C } }
/** @cond */
/**
External reference to the RAMPARTITION Protocol GUID defined
in the .dec file.
*/
extern EFI_GUID gEfiRamPartitionProtocolGuid;
/** @endcond */
typedef struct _RamPartition
{
UINT64 Base;
UINT64 AvailableLength;
}RamPartitionEntry;
/** @} */ /* end_addtogroup efi_ramPartition_data_types */
/*==============================================================================
API IMPLEMENTATION
==============================================================================*/
/* ============================================================================
** Function : EFI_RamPartition_GetRamPartitionVersion
** ============================================================================
*/
/** @ingroup efi_ramPartition_getRamVersion
@par Summary
Gets the RAM Partition table version.
@param[in] This Pointer to the EFI_RAMPARTITION_PROTOCOL instance.
@param[out] MajorVersion Pointer to UINT32 which returns RAM partition table version
@param[out] MinorVersion Pointer to UINT32 which returns RAM partition table version
@return
EFI_SUCCESS -- Function completed successfully. \n
EFI_PROTOCOL_ERROR -- Error occurred during the operation.
*/
typedef
EFI_STATUS
(EFIAPI *EFI_RAMPARTITION_GETRAMPARTITIONVERSION)(
IN EFI_RAMPARTITION_PROTOCOL *This,
OUT UINT32 *MajorVersion,
OUT UINT32 *MinorVersion
);
/* ============================================================================
** Function : EFI_RamPartition_GetHighestBankBit
** ============================================================================
*/
/** @ingroup efi_ramPartition_getHighestBankBit
@par Summary
Gets the RAM Partition table version.
@param[in] This Pointer to the EFI_RAMPARTITION_PROTOCOL instance.
@param[out] HighestBankBit Pointer to Highest Bank Bit
@return
EFI_SUCCESS -- Function completed successfully. \n
EFI_PROTOCOL_ERROR -- Error occurred during the operation.
*/
typedef
EFI_STATUS
(EFIAPI *EFI_RAMPARTITION_GETHIGHESTBANKBIT)(
IN EFI_RAMPARTITION_PROTOCOL *This,
OUT UINT32 *HighestBankBit
);
/* ============================================================================
** Function : EFI_RamPartition_GetMinPasrSize
** ============================================================================
*/
/** @ingroup EFI_RamPartition_GetMinPasrSize
@par Summary
Gets the MinPasrSize
@param[in] This Pointer to the EFI_RAMPARTITION_PROTOCOL instance.
@param[out] MinPasrSize Pointer to MinPasrSize
@return
EFI_SUCCESS -- Function completed successfully. \n
EFI_PROTOCOL_ERROR -- Error occurred during the operation.
*/
typedef
EFI_STATUS
(EFIAPI *EFI_RAMPARTITION_GETMINPASRSIZE)(
IN EFI_RAMPARTITION_PROTOCOL *This,
OUT UINT32 *MinPasrSize
);
/* ============================================================================
** Function : EFI_RamPartition_GetRamPartitions
** ============================================================================
*/
/** @ingroup efi_ramPartition_getRamPartitions
@par Summary
Gets the Ram version as read from the hardware register.
@param[in] This Pointer to the EFI_RAMPARTITION_PROTOCOL instance.
@param[out] pnVersion Pointer to a UINT32 passed by the caller that
will be populated by the driver.
@return
EFI_SUCCESS -- Function completed successfully. \n
EFI_BUFFER_TOO_SMALL -- Returns number of partitions available
EFI_PROTOCOL_ERROR -- Error occurred during the operation.
*/
typedef
EFI_STATUS
(EFIAPI *EFI_RAMPARTITION_GETRAMPARTITIONS)(
IN EFI_RAMPARTITION_PROTOCOL* This,
OUT RamPartitionEntry *RamPartitions,
IN OUT UINT32 *NumPartition
);
/*===========================================================================
PROTOCOL INTERFACE
===========================================================================*/
/** @ingroup efi_ramPartition_protocol
@par Summary
Ram Information Protocol interface.
@par Parameters
*/
struct _EFI_RAMPARTITION_PROTOCOL {
UINT64 Revision;
EFI_RAMPARTITION_GETRAMPARTITIONVERSION GetRamPartitionVersion;
EFI_RAMPARTITION_GETHIGHESTBANKBIT GetHighestBankBit;
EFI_RAMPARTITION_GETRAMPARTITIONS GetRamPartitions;
EFI_RAMPARTITION_GETMINPASRSIZE GetMinPasrSize;
};
#endif /* __EFIRAMPARTITION_H__ */
我们注意到这些相同的形式:
typedef
EFI_STATUS
(EFIAPI *EFI_RAMPARTITION_GETRAMPARTITIONS)(
IN EFI_RAMPARTITION_PROTOCOL* This,
OUT RamPartitionEntry *RamPartitions,
IN OUT UINT32 *NumPartition
);
这是一个指向函数的指针类型的定义,它定义了一个新的指针类型叫EFI_RAMPARTITION_GETRAMPARTITIONS
,如此是希望今后的系统能直接使用EFI_RAMPARTITION_GETRAMPARTITIONS
类型,这样做主要希望能够提高代码的可读性。
这个指针类型指向了一个函数,这个函数有3个输入参数:This
、RamPartitions
、NumPartition
其他函数也是通过同样的方法定义出来的,下面会用到。
再看看文末最后的那一个结构体:
/*===========================================================================
PROTOCOL INTERFACE
===========================================================================*/
/** @ingroup efi_ramPartition_protocol
@par Summary
Ram Information Protocol interface.
@par Parameters
*/
struct _EFI_RAMPARTITION_PROTOCOL {
UINT64 Revision;
EFI_RAMPARTITION_GETRAMPARTITIONVERSION GetRamPartitionVersion;
EFI_RAMPARTITION_GETHIGHESTBANKBIT GetHighestBankBit;
EFI_RAMPARTITION_GETRAMPARTITIONS GetRamPartitions;
EFI_RAMPARTITION_GETMINPASRSIZE GetMinPasrSize;
};
这里又定义了一个大的结构类型_EFI_RAMPARTITION_PROTOCOL
,注意到这个结构几乎是由之前提及的指针函数所构成的。
这样定义是显而易见的,既然是约定的定义,那么自然需要约定的函数的定义。
这个结构体是对应的Protocol
的最主要的组成部分。
GUID
除此之外,一个Protocol还有一些其他的组成部分。
/* Protocol GUID definition */
/** @ingroup efi_ramPartition_protocol */
#define EFI_RAMPARTITION_PROTOCOL_GUID \
{ 0x5172FFB5, 0x4253, 0x7D51, { 0xC6, 0x41, 0xA7, 0x01, 0xF9, 0x73, 0x10, 0x3C } }
/** @cond */
/**
External reference to the RAMPARTITION Protocol GUID defined
in the .dec file.
*/
extern EFI_GUID gEfiRamPartitionProtocolGuid;
/** @endcond */
首先是GUID,正如Windows下的COM Interfaces一样,每一个Protocol也有一个定义好的,唯一的标识符。这个标识符就用GUID来表达。这样一来每个Protocol都有了自己的名字,那么使用者可以方便的通过指明不同的GUID来得到不同的Protocol。
其次是一个指向GUID的全局指针变量,比如这里提到的这个_EFI_RAMPARTITION_PROTOCOL
,就有一个全局的指针叫gEfiRamPartitionProtocolGuid
的指针,它是EFI_GUID *
结构的。
这样做事实上完全是为了方便,他的变量名的命名规则是统一的,即g + Efi + Protocol 名称 + ProtocolGuid。这样一来,程序员就不需记住相应GUID具体的值,而只在需要GUID作为参数的时候,使用这个全局变量即可,这有点类似Windows下的UUID宏。
实现
在boot_images/QcomPkg/Drivers/EnvDxe/EnvDxe.c
中实现了上文提到的协议:
STATIC EFI_RAMPARTITION_PROTOCOL RamPartitionProtocol =
{
EFI_RAMPARTITION_PROTOCOL_REVISION,
EFI_GetRamPartitionVersion,
EFI_GetHighestBankBit,
EFI_GetRamPartitions,
EFI_GetMinPasrSize
};
EFI_STATUS
SetupRamPartitionProtocol ()
{
EFI_STATUS Status;
STATIC EFI_HANDLE ImageHandle;
Status = InitRamPartitionTableLib();
if (Status != EFI_SUCCESS)
return EFI_UNSUPPORTED;
Status = gBS->InstallMultipleProtocolInterfaces (&ImageHandle,
&gEfiRamPartitionProtocolGuid,
&RamPartitionProtocol,
NULL, NULL);
return Status;
}
具体的内容我们就不再往下看,但是可以推测,在这里绑定了对应的函数;之后只要得到gEfiRamPartitionProtocolGuid
的地址,就可以访问到有关的接口。
这也就是所谓的:在XBL中实现了protocol,也就是驱动,在ABL中可以直接调用。
高通平台UEFI有关介绍的更多相关文章
- 高通平台 lcd driver 调试小结
一.概述 1.1 简介 本文档主要包括LCD模块的驱动流程分析.Framebuffer相关知识.Gralloc等相关内容,以及LCD调试的一些经验和相关bug的分析和讲解. 1.2 开发环境 And ...
- 高通平台msm8909 LK 实现LCD 兼容
前段时间小米出现红米note2 换屏门,现在我们公司也要上演了:有两个供应商提供不同IC 的LCD panel. 软件区分的办法是读取LCD IC 的ID 寄存器,下面解析高通平台LK中LCD兼容的过 ...
- 【转】高通平台android 环境配置编译及开发经验总结
原文网址:http://blog.csdn.net/dongwuming/article/details/12784535 1.高通平台android开发总结 1.1 搭建高通平台环境开发环境 在高通 ...
- 高通平台的bootloader过程【转】
====================基本知识=======================LK是(L)ittle (K)ernel的缩写.高通平台android普遍采用LK作为其bootloade ...
- 高通平台Bootloader启动流程【转】
本文转载自:http://blog.csdn.net/fang_first/article/details/49615631 ====================基本知识============= ...
- [修改高通平台WIFI MAC 地址] & [adb over wifi]
[修改高通平台WIFI MAC 地址]fccmd --helpfccmd startfccmd getwifimacfccmd setwifimac 74:AC:5F:F5:D7:40 [adb ov ...
- Android上HDMI介绍(基于高通平台)
本文重点针对HDMI在android上的应用,而比较相关的就是overlay机制.overlay在这里只是简单的介绍,后续会有文章再专门详述. 我没记错的话,高通从7X30开始,平台就可以支持HDMI ...
- 高通平台MSM8916LCM模块移植(一)-bootloader部分
此次移植打算分成两个模块来说,bootloader部分和kernel部分.在实际的移植调试过程中也是这么分成了两个部分分别调试. 高通平台中的bootloader叫做LK(Little Kernel, ...
- 高通平台MSM8916LCM模块移植(一)-bootloader部分【转】
本文转载自:http://www.mobile-open.com/2016/970947.html 高通平台中的bootloader叫做LK(Little Kernel,对于LCM来说LK部分相当重要 ...
- android 6.0 高通平台sensor 工作机制及流程(原创)
最近工作上有碰到sensor的相关问题,正好分析下其流程作个笔记. 这个笔记分三个部分: sensor硬件和驱动的工作机制 sensor 上层app如何使用 从驱动到上层app这中间的流程是如何 Se ...
随机推荐
- 一键启动的AI离线知识库,无需复杂环境依赖,小白都能上手了
简介 在人工智能技术飞速发展的今天,我们经常面临一个挑战:如何快速.简便地部署和使用AI技术?AntSK项目,一个开源的AI知识库和智能体,就是为了解决这一问题而诞生的.现在,我们自豪地宣布,AntS ...
- vue+element设置选择日期最大范围(普通版)
效果是只能跟当天时间有关(30天),下一篇将来的任意时段,比较符合实际 <!DOCTYPE html> <html> <head> <meta charset ...
- van-tab吸顶后头部透明色渐变响应
方法一:监听滚动事件 $('.scrollContent').bind('touchmove', function(e){ var winHeight = $(window) ...
- 由初中生实现的 Windows 12 网页版!
大家好,我是 Java陈序员. 这几天,逛 Github 的时候,看到了一个项目 win12 -- 仿 Windows12 网页版!被它实现的页面功能震撼到了,大家可以一起来感受下! 首先是登录页面. ...
- Typecho博客网站迁移:MySQL ➡️ MarialDB
目录 1. 引言 2. Typecho的自定义配置迁移 3. 数据库迁移:MySQL- > MarialDB 3.1 在原服务器中备份并导出数据库文件 3.2 将"backupdb.s ...
- git学习--GitHub上如何进行PR(Pull Request)操作
目录 一.前言 二.实现步骤 2.1 将小红在GitHub上的Repository clone到小明的本地电脑 2.1.1 fork小红在GitHub上的Repository到小明的GitHub 2. ...
- cesium教程3-加载3dtile模型,并调整位置
直接上示例代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- P3622 [APIO2007] 动物园 -题解
好写 爱写 没事干 所以有了这篇题解 洛谷P3622 [APIO2007] 动物园 题解 $Link$ hzoi题库 洛谷 题目说的挺繁琐,其实就传达了一个很简单的信息: \(n\)个动物,\(c\) ...
- uniapp 配置 基座调试指定页面
在用hbuildx时,用自定义基座,调试程序时,有的页面因为基座缺少组件而进不去,这个时候就可以用指定页面的方式,我们只需要把进入页面的入参传进去,这个时候打开页面就是指定要调试的页面了. 就在pag ...
- C# wpf 实现截屏框实时截屏功能
wpf截屏系列第一章 使用GDI+实现截屏第二章 使用DockPanel制作截屏框第三章 实现截屏框实时截屏(本章)第四章 使用ffmpeg命令行实现录屏 文章目录wpf截屏系列前言一.实现步骤1.获 ...