Note: XBL for Qualcomm

Qualcomm 的平台從原本的 自家的SBL (Second Boot Loader) 改成走 UEFI 的 XBL (eXtensible Boot loader)

而且Toolchain 從以前的ARM DS-5 改成自家的Snapdragon LLVM, 最新的LLVM 是4.0.2(Oct. 2017), 但是平台上用的 XBL toolchain 可能是舊的

要看ReleaseNote 裡面用的版本, 因為他基於 的版本不同, 跟改進的週期因素, 常常Compiler optional 關鍵字會起變化 需要特別的版本才能正確的re-build XBL (最近遇到必須是 SD LLVM 3.5.x, 但是官方支援管道, 極有可能會遇到不熟的跟你扯半天也沒正確結果)

今天找了一下 這有一個 For Android NDK 用的版本 但是可以順利Rebuild XBL




Note: How to use SD LLVM 3.9.x toolchain to rebuild devcfg/QSEE 4.0

need modify  toolchain path, I modify the below for change to SD llvm 3.9.9

--- a/trustzone_images/build/ms/
+++ b/trustzone_images/build/ms/

@@ -9,16 +9,16 @@ unamestr=`uname`
-export LLVMROOT=/pkg/qct/software/llvm/release/arm/
+export LLVMROOT=/media/kunyi/Works/qcom-llvm/v3.9.9
-export LLVMLIB=$LLVMROOT/lib/clang/3.5.2/lib/linux
-export MUSLPATH=$LLVMROOT/tools/lib64
-export MUSL32PATH=$LLVMROOT/tools/lib32
+export LLVMLIB=$LLVMROOT/lib/clang/3.9.9/lib/linux
+export MUSLPATH=$LLVMROOT/aarch64-linux-gnu/libc
+export MUSL32PATH=$LLVMROOT/armv7-linux-gnueabi/libc
export LLVMINC=$MUSLPATH/include
export LLVM32INC=$MUSL32PATH/include
-export GNUROOT=/pkg/qct/software/arm/linaro-toolchain/aarch64-none-elf/4.9-2014.07
-export GNUARM7=/prj/llvm-arm/home/common/build_tools/gcc-linaro-arm-linux-gnueabihf-4.8-2014.02_linux
+export GNUROOT=/media/kunyi/Works/gcc-linaro-aarch64-none-elf-4.9-2014.07_linux
+export GNUARM7=/media/kunyi/Works/gcc-linaro-arm-linux-gnueabihf-4.8-2014.02_linux

and modify to support 3.9.x version toolchain

diff --git a/trustzone_images/tools/build/scons/scripts/ b/trustzone_images/tools/build/scons/scripts/
index 0133201..b4daab7 100755
--- a/trustzone_images/tools/build/scons/scripts/
+++ b/trustzone_images/tools/build/scons/scripts/
@@ -222,6 +222,11 @@ def generate(env):
+   if llvmbin.find("3.9")!= -1:
+    LinkByQCLD=True
+    is39llvm=True
+    LinkByGNU=False
    # GNU path definitions - begin
@@ -293,10 +298,13 @@ def generate(env):
    -enable-android-compat: is to use hardware div which is available on QC hardware, so keep it.
    -mllvm -post-RA-scheduler=false is added a workaround for  issue in the scheduling algorithm, due to which when we select -mcpu=cortex-a7 , clang gets infinitely hung'''
    if do_64:
-      if is37llvm:
-        LLVMFlags += " -target aarch64-linux-gnu -w -mllvm -aarch64-strict-align -mcpu=cortex-a53 -mllvm -enable-global-merge=false -nostdinc -mllvm -inline-threshold-multicaller-size=20 "
+      if is39llvm:
+        LLVMFlags += " -target aarch64-linux-gnu -w -mcpu=cortex-a53 -mllvm -enable-global-merge=false -nostdinc -mllvm -inline-threshold-multicaller-size=20 "
-        LLVMFlags += " -target aarch64-linux-gnu -Werror -mllvm -aarch64-strict-align -mcpu=cortex-a53 -mllvm -enable-global-merge=false -nostdinc "
+        if is37llvm:
+            LLVMFlags += " -target aarch64-linux-gnu -w -mllvm -aarch64-strict-align -mcpu=cortex-a53 -mllvm -enable-global-merge=false -nostdinc -mllvm -inline-threshold-multicaller-size=20 "
+        else:
+            LLVMFlags += " -target aarch64-linux-gnu -Werror -mllvm -aarch64-strict-align -mcpu=cortex-a53 -mllvm -enable-global-merge=false -nostdinc "
       #env.Replace(AS = ARMBIN + "armasm${EXE_EXT} -g --no_unaligned_access ")
       if UseClangAs:
          #env.Replace(AS = "clang_wrap " + "aarch64-linux-gnu-as -c ")
@@ -314,10 +322,13 @@ def generate(env):
          ASM_DBG = "-g "
       do_32 = True
-      if is37llvm:
+      if is39llvm:
         LLVMFlags += " -target arm-linux-gnueabi -w -mfloat-abi=softfp -mllvm -enable-android-compat -mcpu=cortex-a7 -mllvm -post-RA-scheduler=false -mno-unaligned-access  -mllvm -inline-threshold-multicaller-size=20 "
-        LLVMFlags += " -target arm-linux-gnueabi -Werror -mfloat-abi=softfp -mfpu=none -fno-vectorize-loops -mllvm -enable-android-compat -mcpu=krait2 -mno-unaligned-access "        
+        if is37llvm:
+            LLVMFlags += " -target arm-linux-gnueabi -w -mfloat-abi=softfp -mllvm -enable-android-compat -mcpu=cortex-a7 -mllvm -post-RA-scheduler=false -mno-unaligned-access  -mllvm -inline-threshold-multicaller-size=20 "
+        else:
+            LLVMFlags += " -target arm-linux-gnueabi -Werror -mfloat-abi=softfp -mfpu=none -fno-vectorize-loops -mllvm -enable-android-compat -mcpu=krait2 -mno-unaligned-access "        
       #env.Replace(AS = ARMBIN + "armasm${EXE_EXT} --apcs /noswst/interwork --no_unaligned_access ")
       if UseClangAs:
         env.Replace(AS = LLVMBIN + "clang${EXE_EXT} -target arm-linux-gnu -mfloat-abi=softfp -mcpu=cortex-a8 -x assembler -allow-integrated-as-for-asm-input -c ")


Note: BAM/BLSP_UART IRQ Table for MSM8996


BLSP1:MasterID:86, BAM IRQ: 238, Below Core IRQ

  • BLSP1_QUP1, 95
  • BLSP1_QUP2, 96
  • BLSP1_QUP3, 97
  • BLSP1_QUP4, 98
  • BLSP1_QUP5, 99
  • BLSP1_QUP6, 100
  • BLSP1_UART1,107
  • BLSP1_UART2,108
  • BLSP1_UART3,109
  • BLSP1_UART4,110
  • BLSP1_UART5,111
  • BLSP1_UART6,112

BLSP2:MasterID:84, BAM IRQ: 239, Below Core IRQ

  • BLSP2_QUP1, 101
  • BLSP2_QUP2, 102
  • BLSP2_QUP3, 103
  • BLSP2_QUP4, 104
  • BLSP2_QUP5, 105
  • BLSP2_QUP6, 106
  • BLSP2_UART1,113
  • BLSP2_UART2,114
  • BLSP2_UART3,115
  • BLSP2_UART4,116
  • BLSP2_UART5,117
  • BLSP2_UART6,118

Note: Rebuild TrustZone/QSEE 4.0 image for OEM

Just following the below steps, must remove -mno-ae compiler optional from

  1. Prepare Toolchain from CreatePoint (now SD LLVM 3.7.6),
    and linaro gcc (maybe you can to check step 2 first, to get gcc version)
  2. modify to setting toolchain path
  3. use clean build command ./ CHIPSET=<target> devcfg sampleapp

more detail ref. BSP user manual.


Note: SBL/LK on Qualcomm

目前看起來已經是UEFI base了, 做的事情差不多一樣

基本上就是載入下面的東西跟初始化PMIC/DDR, 已經支援DDR trainingCDT

  1. PMIC
  2. DDR init
  3. QSEE
  4. APDP
  5. SEC
  6. EFS
  7. QHEE
  8. RPM
  9. STI
  10. APPSBL

之後就跳進LK 去把全部載入的image 啟動起來, 可以從Log 看到那時把TZ/RPM等等連接起來
之後點LCD panel, 顯示開機畫面 然後執行Verify Boot確認Bootloader status 才去載入 Kernel


  • boot_images/QcomPkg/Tools/
  • boot_images/QcomPkg/MsmXXXXPkg/Library/XBLLoaderLib/boot_cdt_array.c

Note: Qualcomm with Device Tree Blob


簡單講就是修改 Android Boot image 的 header 在加上 QCDT (Qualcomm Configuration Data Table)

然後在Bootloader 期間收集版上的硬體資訊去比較 PLATFORM/SOC/PMIC/REVISION 找到最接近的DTBs

  1) LK bootloader will obtain platform id/variant/subtype/soc rev/major ver/minor ver
     /pmic0/pmic1/pmic2/pmic3 info either from early bootloaders or via other means
  2) LK bootloader will check entries #10 for non-zero
     value (set to zero for standard boot.img).  If the
     value is non-zero, refer to page section after
     the "second stage" in the boot.img layout
  3) Check QCDT magic
  4) Check QCDT version (optional LK to handle multiple
     QCDT version)
  5) LK scans through the QCDT table to look for matching
     entry.  Search order is:
     1) msm ID exact match
     2) Platform type exact match
     3) subtype ID exact match
     4) HLOS subtype exact match
     5) Pmic0 model ID exact match
     6) Pmic1 model ID exact match
     7) Pmic2 model ID exact match
     8) Pmic3 model ID exact match
     9) foundry ID, look for exact match, if not found choose
    device tree with foundry-id(0x0)
     10) select the highest soc rev in QCDT that is
        equal to or lower than the runtime detected soc rev
     11) select the highest major&minor ver in QCDT that is
        equal to or lower than the runtime detected major ver
     12) select the highest pmic0 major&minor in QCDT that is
        equal to or lower than the runtime detected pmic0
     13) select the highest pmic1 major&minor in QCDT that is
        equal to or lower than the runtime detected pmic1
     14) select the highest pmic2 major&minor in QCDT that is
        equal to or lower than the runtime detected pmic2
     15) select the highest pmic3 major&minor in QCDT that is
        equal to or lower than the runtime detected pmic3
  6) Load the matching DTB blob to the tags addr
7) LK pass the correct DTB to the kernel