1. 程式人生 > >UEFI在高通平臺實現

UEFI在高通平臺實現

UEFI(Unified extensible firmware interface)統一的可擴充套件韌體介面,是一種詳細描述型別介面的標準。

可擴充套件韌體介面(Extensible Firmware InterfaceEFI)是 Intel PC 韌體的體系結構、介面和服務提出的建議標準。其主要目的是為了提供一組在 OS 載入之前(啟動前)在所有平臺上一致的、正確指定的啟動服務,被看做是有近20多年曆史的 BIOS 的繼任者。

既然UEFI是為了取代BIOS的,自然有他自己的優勢。

BIOS是彙編實現的,採用的是16bit 真實模式定址方式,最大支援的記憶體只有1M,程式碼易讀性以及實現的功能都受到限制,而且移植起來不方便。

BIOS支援的最大磁碟空間不超過2TB

UEFI克服了上述的所有缺點,採用C語言實現,分層,模組化設計,實現了CPU以及驅動的無關性。UEFI可以理解為一個完整的系統,包含了上電時序,驅動實現,os環境建立(這個os可以理解為UEFI執行獨有的os,非linuxwindows),應用程式。其中應用程式支援網路配置,類shell環境,fastbootlinux loader等。

其中UEFI中涉及的名詞縮寫:

Unified extensible firmware interface (UEFI)

SECsecurity

PEIpre EFI initialization

DXE

driver execution Environment

BDSBoot Dev Select

TSLTransient System Load

RT runtime

ALafter life

GUIDGlobally Unique Identifier

CSM : Compatibility Support Module

TCGTrusted Computing Group

PEportable executable

COFF:Common object file format

FV:Firmware Volume


對於高通的平臺UEFI的實現分成了兩部分:

1.    XBL

包含了晶片相關的協議和關鍵的應用(例如充電)

2.    ABL包含了晶片無關的應用,比如fastbootlinuxloader

UEFI程式碼中大量使用了protocol概念,這個protocol其實指的是驅動,包含了驅動函式指標和資料。以rampatition為例:

boot_images/QcomPkg/Include/Protocol/EFIRamPartition.h中聲明瞭了rampatition protocol

typedef

EFI_STATUS

(EFIAPI *EFI_RAMPARTITION_GETRAMPARTITIONS)(

   INEFI_RAMPARTITION_PROTOCOL* This,

   OUTRamPartitionEntry         *RamPartitions,

   IN OUT UINT32                 *NumPartition

   );struct_EFI_RAMPARTITION_PROTOCOL {

   UINT64                                  Revision;

  EFI_RAMPARTITION_GETRAMPARTITIONVERSION GetRamPartitionVersion;

  EFI_RAMPARTITION_GETHIGHESTBANKBIT     GetHighestBankBit;

   EFI_RAMPARTITION_GETRAMPARTITIONS       GetRamPartitions;

};

在boot_images/QcomPkg/Drivers/EnvDxe/EnvDxe.c中實現了該協議

STATIC EFI_RAMPARTITION_PROTOCOL RamPartitionProtocol =

{

  EFI_RAMPARTITION_PROTOCOL_REVISION,

  EFI_GetRamPartitionVersion,

  EFI_GetHighestBankBit,

  EFI_GetRamPartitions

};

在XBL中實現了protocol,也就是驅動,在ABL中可以直接使用。


UEFI啟動流程:

對於高通平臺啟動過程依次為PBL->XBL->ABL.


一般使用者定製化主要集中在ABL中,這部分程式碼樹如下:

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

這部分裡面主要是支援linuxloader 用來載入linux,以及fastboot。使用者修改主要集中在這兩個部分,入口函式LinuxLoaderEntry。

UEFI中用到幾種字尾格式的檔案說明:

fdf:flash definitionfile,描述flash分割槽地址範圍

dec:package declarationfile,定義了不同模組的GUID資訊

dsc:description file,主要包含需要用到的所有inf檔案

inf:單個模組的編譯資訊,類似makefile

efi :最終編譯生成的UEFI可執行檔案