高通平台UEFI有关介绍

高通平台UEFI有关介绍

背景

我需要在高通平台上学习点亮LCD,目前通过同事在别的平台的配置代码,我已经将kernel部分的屏幕点亮了;剩余的工作量就在BP侧,也就是系统刚开机的那一段时间。在开发过程中,我发现我对BP侧的开发有点不太熟悉,因此我需要搞清楚有关的概念。只有搞清楚了这些基本概念,我才能够在后续的工作中不留下隐患。

有关文档:

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从上电到关机,一共有七个阶段:

  1. SEC(安全验证)
    其功能包括:接受处理系统启动与重启信号、初始化临时RAM区、作为可信系统的根、以及传递系统参数到下一阶段。
    其执行流程是:
    上电 -> ResetVector -> SEC函数入口 -> PEI函数入口
  2. PEI
    主要功能是为DXE准备执行环境,将HOB列表传递给DXE。此阶段到后期内存才被初始化,所以资源相当有限,尚未可进行复杂的工作。
  3. DXE
    此阶段执行大部分系统初始化工作,内存已被初始化,可以进行大量复杂工作。当所有的Driver都执行完毕,说明系统初始化完成,接着通过EFI_BDS_ARCH_PROTOCAL找到BDS并调用BDS的入口函数,进入BDS阶段。
  4. BDS
    此阶段主要功能是执行启动策略,等OS Loader启动后,系统进入TSL阶段。
  5. TSL
    TSL是OS Loader执行的第一阶段,OS Loader在这个阶段作为UEFI APPLICATION运行,当ExitBootServices服务被调用后,进入RT(RunTime)阶段。
  6. RT
    系统进入此阶段后,系统控制权从UEFI内核转交到OS Loader上。随着OS Loader的执行,OS最终取得对系统的 控制权。
  7. 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代码的一部分,属于高通私有代码。

// todo
UEFI代码中大量使用了protocol概念,这个protocol其实指的是驱动,包含了驱动函数指针和数据。以rampatition为例:

boot_images/QcomPkg/Include/Protocol/EFIRamPartition.h中声明了了rampatition protocol:

ABL

ABL包括芯片无关的应用如fastboot。ABL则在开源Linux Android代码树里。

ABL的编译非常简单,依次执行命令:

source build/envsetup.sh
lunch 32
make  aboot

不同的厂商对UEFI有不同的实现,一种比较常用的开源实现是EDK2;EDK2是一个遵循UEFI标准和PI标准的跨平台固件开发环境,EDK2支持多种操作系统, 也支持跨平台编译。

确切来讲,高通所使用的edk2即为ABL部分的代码。

高通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

  • 需要驱动DisplayUsbKeypadPmicVibrator

Uboot 的特点:

  • 加载引导linux kernel

  • 发展早,软件成熟稳定,功能完备;

  • 支持的多个CPU 体系

  • 支持复杂驱动,如Fs/Network等等;

Little Kernel特点:

  • 加载引导linux kernel

  • 轻量级、不支持复杂的驱动

上一篇:C#用DesignSurface实现一个简单的窗体设计器


下一篇:软件质量管理: