I compared UEFI bootloaders from Google Pixel XL, 2XL, 3XL, and Lenovo Miix 630 to show how Qualcomm used the flexibility of UEFI to support Android and Windows.

Introduction

This is part 1 of a series about Qualcomm bootloaders. Part 2 will be posted in about a month. Sign up with your email to be the first to read the next post:


Qualcomm’s Snapdragon CPUs power most Android smartphones, with a 42% market share. The Snapdragon 835 is also the only ARM64 processor supported by Windows 10 as part of the Always Connected PC initiative. To securely and reliably support the variety of hardware and software on these diverse devices during startup, Qualcomm chose to boot their CPUs using the Unified Extensible Firmware Interface (UEFI) standard.

When I first saw this, I was appalled: UEFI is usually used on PCs, laptops, and servers; wouldn’t a UEFI implementation for mobile phones be unnecessarily bloated? I decided to find out.

I examined the firmware of four different devices: all three generations of the Pixel Android phones by Google, and one Windows 10 tablet by Lenovo.

I found that UEFI is actually very flexible: each functionality is encapsulated in its own module, so it’s easy to build a firmware with only the needed components.

Snapdragon 820

The Snapdragon 820 is the first Qualcomm CPU that uses UEFI on Android devices. (Previous Qualcomm chips only used UEFI to boot Windows Phone.)

The UEFI firmware on Qualcomm chips is contained in the XBL - the eXtensible BootLoader. This is composed of two components: the SBL (Secondary BootLoader) executes first to initialize the RAM before passing control to the UEFI firmware.

The Snapdragon 820 doesn’t actually use UEFI to boot Android directly: instead, the UEFI firmware immediately loads the old aboot bootloader, the same modified version of the Little Kernel bootloader used by every previous Qualcomm CPU to load Android.

Because of the limited duties of the UEFI implementation, the first generation Pixel XL’s XBL doesn’t include too many drivers.

I listed the files in the XBL with @theopolis’s uefi-firmware-parser:

uefi-firmware-parser -b marlin-ppr2.181005.003/images/xbl.img

This gave me a list of files in the UEFI bootloader, linked here.

You can see that there’s two Firmware Volumes (FV), one inside the other. A firmware volume is an archive of files; the outer one is uncompressed, and contains the Sec executable. This is the entry point of the UEFI firmware, and it decompresses and runs the inner volume.

There are 56 drivers in the UEFI implementation, each driving one part of the system. There’s also a few applications used for debugging, such as a USB Mass Storage app that exports the phone’s storage (UsbfnMsdApp) and a UEFI prototype implementation of Android’s Fastboot, not used on this device.

It’s clear that the UEFI firmware on the Snapdragon 820 is transitional: it still contains many extraneous debugging applications, and is only used to launch the “real” aboot bootloader.

Snapdragon 835

By the Snapdragon 835, the UEFI bootloader is mature enough to boot Android on its own, and so Little Kernel has been replaced by abl, consisting of a UEFI version of Fastboot and a Linux bootloader.

The XBL’s format also changed: the inner Firmware Volume is now compressed with Gzip, which uefi-firmware-parser can’t natively unpack. 7zip, of course, can unpack it just fine.

uefi-firmware-parser -b -e taimen-ppr2.181005.003/images/xbl.img
7z x volume-491008/file-9e21fd93-9c72-4c15-8c4b-e77f1db2d792/section0.guid
uefi-firmware-parser -b section0

Here’s the list of files for the outer and inner firmware volumes.

Qualcomm has removed most of the debugging apps from the bootloader: with this change, the firmware shrinks from 7MB uncompressed on the Pixel XL to only 4MB uncompressed on the Pixel 2XL, despite taking on more duties, such as off-mode charging (with the new QcomChargerApp).

We can also examine the new Android bootloader:

uefi-firmware-parser -b taimen-ppr2.181005.003/images/abl.img

This gives me this list of files, which shows that the Android bootloader is implemented in one application, LinuxLoader.

Snapdragon 835, Windows 10 ARM64

This is the odd one out: this is from a Lenovo Miix 630, a Windows 10 convertable laptop, not an Android phone. Despite the different OS and form factor, most of the firmware stayed the same.

I downloaded the firmware from Lenovo’s website. Unfortunately, the update file confused uefi-firmware-parser, so I had to manually search for the _FVH magic number in the update to extract the firmware.

dd bs=2581 skip=1 if=8WCN25WW/cap/qcfirmware8998v1.0.1075.2507.cap of=qc8998_lenovo.fv
uefi-firmware-parser qc8998_lenovo.fv

Here’s the list of files.

This firmware has quite a few different components compared to the Android bootloaders:

  • a few extra drivers to load and process ACPI tables
  • more USB drivers, since a laptop may need to enter text in the BIOS via an external keyboard or boot from a USB flash drive
  • and (oddly enough) the ancient prototype Fastboot app last seen on the Snapdragon 820. Maybe this is for flashing at the factory?
  • the inner firmware volume uses standard compression like the Snapdragon 820, and unlike the Android 835 firmware.

Despite all the differences, the basic drivers from the Android bootloader are all still present, and the two bootloaders share the same version number:

Lenovo Miix 630:

UEFI LABEL: UEFI.4.1.$Change: 11894909 $ LABEL DATE: $Date: 2016/12/01 $ FW_VER: 4.1. BUILD_DATE: May 10 2018 BUILD_TIME: 16:47:32 

Pixel 2XL:

UEFI LABEL: UEFI.4.1.$Change: 12642780 $ LABEL DATE: $Date: 2017/03/10 $ FW_VER: 4.1. BUILD_DATE: Jul 13 2018 BUILD_TIME: 15:56:42 

So Qualcomm built one bootloader that, by adding and removing a few components, can boot Android or Windows, demonstrating the value of UEFI.

Snapdragon 845

Finally, the Pixel 3XL uses the latest iteration of UEFI on Snapdragon.

uefi-firmware-parser -b -e crosshatch-pd1a.180720.030/image/xbl.img
7z x volume-549696/file-9e21fd93-9c72-4c15-8c4b-e77f1db2d792/section0.guid
uefi-firmware-parser -b section0

List of files: outer and inner.

Once again, the modular nature of UEFI helps enable new hardware: for example, there’s a new HALIOMMU module to support the IOMMU on Snapdragon 845.

The Android bootloader got a refactor as well:

uefi-firmware-parser -b crosshatch-pd1a.180720.030/image/abl.img

The list of files show that the Android bootloader has been refactored into three components: one application for Fastboot flashing, one application for booting the Linux kernel, and one driver for handling Fastboot USB communications, likely based on EDK2’s driver. This shows that UEFI allows better program organization and code reuse through modular drivers and applications.

In addition, there’s a TrueType font in the list of files: it seems Google took advantage of the sophisticated UEFI runtime to support more elegant user interfaces during startup, improving the user’s first impression of the device during boot.

Conclusion

Qualcomm’s switch to UEFI for their bootloader firmware took more than a generation of CPUs to complete, but gave them the flexibility to develop one bootloader for two OSes and to refactor their code into more easily manageable modules.

What I learned

  • How to unpack Qualcomm XBL images
  • The evolution of Qualcomm’s UEFI firmware

What I need to learn next

  • Modifying and repacking a Qualcomm bootloader.
  • Finding a way to chainload a modified bootloader without touching the original bootloader