1. 程式人生 > 實用技巧 >高通平臺UEFI有關介紹

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

  • 輕量級、不支援複雜的驅動