高通平臺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
程式碼的一部分,屬於高通私有程式碼。
// 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
-
需要驅動
Display
、Usb
、Keypad
、Pmic
、Vibrator
Uboot 的特點:
-
載入引導linux kernel
-
發展早,軟體成熟穩定,功能完備;
-
支援的多個CPU 體系
-
支援複雜驅動,如Fs/Network等等;
Little Kernel特點:
-
載入引導linux kernel
-
輕量級、不支援複雜的驅動