Experiencing UEFI on RK3588
Unified Extensible Firmware Interface
UEFI is a firmware technology originating from Intel, initially developed under the codename Tiano. The project began around the early 2000s when firmware code was outdated, primarily written in assembly and C languages, complicated and cumbersome, making it hard to maintain and extend. Meanwhile, Intel was heavily investing in the Itanium project, which required many groundbreaking innovative designs and modifications at the firmware level. Making these modifications on the outdated BIOS was very challenging. Thus, the Tiano project was born, introducing popular COM technology at the time, commonly using interface technology, using GUIDs to represent interfaces, and replacing C with C++.
# Great Firmware
In 2004, the Tiano project was initially completed and officially released under the name EFI. On Intel’s website, you can find a press release from that year:
Intel Invites Industry In Design Of Technology To Succeed BIOS, Industry Collaboration Key in Addressing Oldest Software Technology in PC Platforms.
The title suggests that Intel leads the industry in designing new technology to replace BIOS, focusing on the oldest software technology in PC platforms.
It is quite appropriate to refer to BIOS as the oldest software technology on PC platforms. Indeed, BIOS originated from the now-historical CP/M operating system and DRI company, invented by Gary Arlen Kildall, the founder of DRI. I detailed Gary’s legendary life and his tremendous contributions to the PC industry and system software in the sixth chapter of “A Brief History of Software” titled “The Dragon’s Regret”.


About PC Software in “A Brief History of Software”
And the Roots of BIOS Technology
Kildall was a pioneer of PC technology. When Intel was developing the 8086, he was Intel’s software consultant. At the time he became famous, Bill Gates was still searching for direction, and Gates visited Kildall’s home several times for advice. Some subtle information can be seen in the photo below.

Bill Gates (center) with Kildall (right)
The core value of firmware technology is to isolate hardware differences, allowing the operating system to manage a wide variety of constantly changing hardware through a unified interface. This was precisely the intention behind Gary Arlen Kildall’s invention of BIOS technology. This value was also understood by Bill Gates, and thanks to this technology, Microsoft’s Windows operating system was able to run smoothly in the PC era; as long as there was a BIOS box, Windows could be installed.


# Linus’s Furious Criticism of ARM
In 2005, Intel, along with several partners, established the UEFI Forum, marking the beginning of the development of Tiano technology in the form of UEFI. The initial members of the UEFI Forum included:
AMD, American Megatrends, Inc., Dell Inc., HP, Intel Corporation, International Business Machines Corporation, Insyde Software Corp., Microsoft Corp., and Phoenix Technologies Ltd. to Collaborate
Note that ARM is not listed among the members above for various reasons. From the perspective of ARM players, at that time, ARM’s main scenarios were still embedded and vertical fields. For these scenarios, typically, like Apple, one company does the entire software stack, and the pressure for software compatibility is not very high, so the need for firmware layers is not so urgent.


However, as ARM systems became more powerful and more ARM systems began to use the common LINUX kernel, compatibility issues gradually became more serious. Too many manufacturers were continuously merging seemingly similar yet different adaptation codes into the Linux kernel code tree. This phenomenon persisted for several years, leading to the constant expansion of the arch/arm directory in the Linux kernel, filled with numerous directories starting with mach, with no end in sight, and even today, this directory remains so.
Finally, one day, when a person named Tony Lindgren wanted to merge his code into the kernel code tree, he encountered Linus Torvalds in a bad mood and exploded.
From Linus Torvalds <>
Date Thu, 17 Mar 2011 19:50:36 -0700
Subject Re: [GIT PULL] omap changes for v2.6.39 merge window share 292
On Thu, Mar 17, 2011 at 11:30 AM, Tony Lindgren wrote:
>
> Please pull omap changes for this merge window from:
Gaah. Guys, this whole ARM thing is a f*cking pain in the ass. You need to stop stepping on each other’s toes. There is no way that your changes to those crazy clock-data files should constantly result in those annoying conflicts, just because different people in different ARM trees do some masturbatory renaming of some random device. Seriously. That usb_musb_init() thing in arch/arm/mach-omap2/usb-musb.c also seems to be totally insane. I wonder what kind of insanity I’m missing just because I don’t happen to see the merge conflicts, just because people were lucky enough to happen to not touch the same file within a few lines.
Linus is a descendant of poets, and his words are concise. “The whole ARM thing is x. You all must stop digging holes for each other and stepping on each other’s toes.”

# Can Ten Years Forge a Sword
Linus’s furious criticism had an effect. Around 2013, ARM joined the UEFI Forum.

On August 12, 2014, the UEFI Forum released the ACPI 5.1 specification, which included support for ARM, including the ARM interrupt controller GIC and many features of ARMv8. The title of that year’s press release was:
UEFI FORUM’S NEW ACPI 5.1 SPECIFICATION ADAPTS CONFIGURATION AND POWER INTERFACE TO 64-BIT FOCUSED FEATURES OF THE ARMV8-A ARCHITECTURES
The new ACPI 5.1 specification of UEFI adopts configuration and power interfaces supporting ARMv8 64-bit features
Having standard support is a necessary condition but not a sufficient one.
To promote UEFI technology in the ARM ecosystem, ARM has been making efforts, such as ARM’s certification technology called SystemReady, which focuses on UEFI.

Academician Dong Wei from ARM leads this direction.

Since 2013, it has been ten years. What is the status of UEFI on the ARM platform?
Yesterday, a partner from GeDu successfully compiled the UEFI code from hardware partners and flashed it onto the Yulan notebook. The first attempt failed, but the second succeeded, and the familiar UEFI-style setup interface appeared on Yulan.

Upon hearing that after flashing, one could enter the UEFI setup interface upon booting, I was initially very pleased, because it took little time to get the UEFI code running on Yulan, reflecting that ARM’s ten years of effort has yielded results. The firmware technology on the ARM platform has been weak, and being able to display a graphical interface in the firmware stage is a significant milestone. Looking at the entire ARM ecosystem, it is not excessive to say that the total number of ARM systems is in the tens of billions, but having interface firmware is rare, and less than one in a million.
However, hearing that it went directly into the UEFI interface upon booting also made me aware that the situation was not good. Based on my years of understanding of UEFI, automatically entering the graphical interface means that the normal boot has failed. From the perspective of the entire system, firmware primarily runs during the boot phase, and its main mission is to pave the way for the operating system. It should prepare everything and hand over the execution right to the operating system. From this angle, it is somewhat like Tao Zhu Gong (Fan Li) helping King Goujian of Yue to defeat Wu and then retiring to the lakes.
However, currently, UEFI has not successfully handed over control to the OS. This is both unexpected and reasonable.

# Why Did the Handover Fail?
Yulan was originally using u-boot as the firmware, responsible for loading the LINUX kernel and smoothly transitioning control. Both u-boot and Linux are stored on Yulan’s EMMC flash memory. The partition situation of the flash memory is as follows:

Below is the serial output captured by a partner:
DDR V1.09 a930779e06 typ 22/11/21-17:50:56LPDDR4X, 2112MHzchannel[0] BW=16 Col=10 Bk=8 CS0 Row=17 CS=1 Die BW=16 Size=2048MBchannel[1] BW=16 Col=10 Bk=8 CS0 Row=17 CS=1 Die BW=16 Size=2048MBchannel[2] BW=16 Col=10 Bk=8 CS0 Row=17 CS=1 Die BW=16 Size=2048MBchannel[3] BW=16 Col=10 Bk=8 CS0 Row=17 CS=1 Die BW=16 Size=2048MBManufacturer ID:0xffCH0 RX Vref:27.7%, TX Vref:20.8%,0.0%CH1 RX Vref:26.7%, TX Vref:20.8%,0.0%CH2 RX Vref:26.7%, TX Vref:23.8%,0.0%CH3 RX Vref:28.7%, TX Vref:21.8%,0.0%change to F1: 528MHzchange to F2: 1068MHzchange to F3: 1560MHzchange to F0: 2112MHzoutU-Boot SPL board initU-Boot SPL 2017.09-gc060f28d70-220414 # (Apr 18 2022 - 18:13:34)Failed to set cpub01Failed to set cpub23Trying to boot from MMC2MMC: no card presentmmc_init: -123, time 0spl: mmc init failed with error: -123Trying to boot from MMC1Trying fit image at 0x4000 sector## Verified-boot: 0## Checking atf-1 0x00040000 ... sha256(909ea14106...) + OK## Checking uboot 0x00200000 ... sha256(36148e13ec...) + OK## Checking fdt 0x002f0000 ... sha256(c07f4a4d71...) + OK## Checking atf-2 0x000f0000 ... sha256(6a970ae6b4...) + OK## Checking atf-3 0xff100000 ... sha256(3ea8cf0d7e...) + OK## Checking optee 0x08400000 ... sha256(fde0860845...) + OKJumping to U-Boot(0x00200000) via ARM Trusted Firmware(0x00040000)Total: 542.534 ms
INFO: Preloader serial: 2NOTICE: BL31: v2.3():v2.3-468-ge529a2760:derrick.huangNOTICE: BL31: Built : 09:59:49, Nov 21 2022INFO: spec: 0x1INFO: ext 32k is validINFO: ddr: stride-en 4CHINFO: GICv3 without legacy support detected.INFO: ARM GICv3 driver initialized in EL3INFO: valid_cpu_msk=0xff bcore0_rst = 0x0, bcore1_rst = 0x0INFO: system boots from cpu-hwid-0INFO: idle_st=0x21fff, pd_st=0x11fff9, repair_st=0xfff70001INFO: dfs DDR fsp_params[0].freq_mhz= 2112MHzINFO: dfs DDR fsp_params[1].freq_mhz= 528MHzINFO: dfs DDR fsp_params[2].freq_mhz= 1068MHzINFO: dfs DDR fsp_params[3].freq_mh
The above serial print information comes from two software, one is ATF, which is ARM’s trusted firmware, running at the highest privilege level of ARMv8, executing high-security sensitive logic, including mitigating CPU defects and design flaws. The other is u-boot, which has been deeply rooted in the ARM ecosystem for many years. In fact, the firmware package we received is called uboot_uefi, which is actually a mixed version of uefi and uboot. During use, u-boot needs to be used, but it quickly hands over execution to uefi.
For the above print information, UEFI has not been seen yet. After I actually participated in debugging the entire issue, I finally saw the uefi output:
add-symbol-file /extd/guolin/uefi_sdk/uefi_emmc/Build/RK3588/DEBUG_GCC5/AARCH64/EmbeddedPkg/Application/AndroidBoot/AndroidBootApp/DEBUG/AndroidBootApp.dll 0x39828000Loading driver at 0x00039827000 EntryPoint=0x▒Failed to get AndroidBootImg Size: Invalid ParameterError: Image at 00039827000 start failed: Invalid Parameterremove-symbol-file /extd/guolin/uefi_sdk/uefi_emmc/Build/RK3588/DEBUG_GCC5/AARCH64/EmbeddedPkg/Application/AndroidBoot/AndroidBootApp/DEBUG/AndroidBootApp.dll 0x39828000Image Return Status = Invalid Parameter[Bds]Booting Android Fastbootadd-symbol-file /extd/guolin/uefi_sdk/uefi_emmc/Build/RK3588/DEBUG_GCC5/AARCH64/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp/DEBUG/AndroidFastbootApp.dll 0x39829000Loading driver at 0x00039828000 EntryPoint=0x0▒Fastboot: Couldn't open Fastboot Transport Protocol: Not FoundError: Image at 00039828000 start failed: Not Foundremove-symbol-file /extd/guolin/uefi_sdk/uefi_emmc/Build/RK3588/DEBUG_GCC5/AARCH64/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp/DEBUG/AndroidFastbootApp.dll 0x39829000Image Return Status = Not FoundProcess PlatformRecovery0000 (Default PlatformRecovery) ...[Bds] Unable to boot![Bds]Booting UiAppadd-symbol-file /extd/guolin/uefi_sdk/uefi_emmc/Build/RK3588/DEBUG_GCC5/AARCH64/MdeModulePkg/Application/UiApp/UiApp/DEBUG/UiApp.dll 0x30509000Loading driver at 0x00030508000 EntryPoint=0x0003050FE30 UiApp▒[HiiDatabase]: Memory allocation is required after ReadyToBoot, which may change memory map and cause S4 resume issue.
The above various messages represent the UEFI style or the genes from Tiano (original design).
Firstly, the add-symbol-file statement is for debugging, and printing the entire information indicates that UEFI has debugging support that is compatible with the debugger.
Secondly, the file extensions indicated in the above file paths are all dll, as Tiano’s initial development environment was Windows, and the initial compilation tools were also Microsoft’s Visual C++. Therefore, UEFI modules are the popular DLLs on the Windows platform, and the corresponding debugging symbols are in the PDB format used by Microsoft.
The above information contains the names of three DLLs, namely:
AndroidBootApp.dll
AndroidFastbootApp.dll
UiApp.dll
From the names of the apps, these modules belong to extension-type app modules and do not belong to Tiano’s core framework (like DXECORE).
The three DLLs represent UEFI’s three efforts to hand over execution rights after completing the basic work:
First, it attempts to boot the kernel in Android Boot mode.
Then, it tries to boot the kernel in Android FastBoot mode.
If both fail, it has no choice but to run UiApp, displaying the graphical interface.

# Where Are You, Android Magic Code?
By looking up the UEFI source code based on the error message, we can see that the following function reported an error:

This function is to get the size of the kernel. The so-called Android boot mode is to place a segment of descriptive information at a fixed location in flash memory, which needs to conform to the following format:
#pragma pack(1)/* https://android.googlesource.com/platform/system/core/+/master/mkbootimg/bootimg.h */typedef struct { UINT8 BootMagic[ANDROID_BOOT_MAGIC_LENGTH]; UINT32 KernelSize; UINT32 KernelAddress; UINT32 RamdiskSize; UINT32 RamdiskAddress; UINT32 SecondStageBootloaderSize; UINT32 SecondStageBootloaderAddress; UINT32 KernelTaggsAddress; UINT32 PageSize; UINT32 Reserved[2]; CHAR8 ProductName[16]; CHAR8 KernelArgs[ANDROID_BOOTIMG_KERNEL_ARGS_SIZE]; UINT32 Id[32];} ANDROID_BOOTIMG_HEADER;#pragma pack ()
The above information starts with a magic code: ANDROID!
The error code indicates that it did not match this magic code, resulting in an invalid parameter.
In fact, GeDu’s GDK uses this boot method to boot the LINUX kernel. Using the od command to check the boot partition of GDK8, you can see the ANDROID! magic code.

The 4e41 in the above image corresponds to the ASCII codes for N and A.

# GRUB Interruption
During the debugging process of this issue, two different opinions emerged within the team. One opinion was to create a boot disk with GRUB, allowing UEFI to hand over control to GRUB, which would then load the LINUX kernel. The other opinion was to skip GRUB and directly load the LINUX kernel.
I supported the second opinion; since we already have UEFI, and it still includes a u-boot that hasn’t fully retired, there is no need to bring GRUB into the mix. Too many parties performing at the same time would complicate the system and impact boot time.
However, those who held the first opinion quickly made progress, successfully running GRUB on Yulan using the multi-boot target support built into UEFI.

However, I still insisted on the second method. Even if the first method succeeded, the second method also has its value; it would boot faster. So I continued to debug the second method.
The root of the failure was the inability to find the magic code, so we could trace this clue. A simple way was to add print statements to the source code. If this debugging method was unsuccessful, we could utilize the more powerful debugging facility available on Yulan—CoreSight.


# Relentlessly Pursuing the Magic Code
If we can’t read the magic code, the partition location might be specified incorrectly. By examining the source code, we found that the problematic function reads the partition using PCD configuration technology.

Upon searching for the corresponding PCD settings, we indeed found two settings, one set to \EFI\BOOT\GRUBAA64.EFI. The other is set in the form of a UUID partition table, and we should select the second one. However, the first one was actually being used.

UEFI has excellent configurability, and adjusting the INF file can change the PCD settings.

After the adjustment, the serial print information confirmed that UEFI was now using the correct partition.

However, the invalid parameter error still persisted, which meant UEFI had not yet found the appropriate magic code. To address this, I had my partner add print statements to display the data read, and discovered that the magic code position was all zeros.

Since the print used UEFI’s %r format specifier, the four Success in the above image were actually four zeros.
At this point, the target was clear: UEFI was reading from the wrong partition location, so it was reading all zeros. With solid data to support this, my partner carefully reviewed the PCD parameters and found that the starting position in the parameters was incorrect.
Since the PCD string was long, I had been focusing on verifying the UUID and had not noticed the starting position and partition size part after the UUID.
L"VenHw(100C2CFA-B586-4198-9B4C-1683D195B1DA)/HD(3,GPT,7A3F0000-0000-446A-8000-702F00006273,0x8000,0x20000)"
After correcting the partition information, UEFI successfully handed over the execution rights to the kernel, and the UEFI interface no longer appeared automatically. Instead, the Yulan icon emerged, a flower flashing on the black screen, with bright green leaves, golden yellow petals, and a red-yellow center, blooming proudly yet slightly shyly, as it stands alone, unique and distinct.


As mentioned in the press release from Intel, it specifically described that the Tiano project involved more than 200 people in development, at Intel’s Shanghai Software Center, and laboratories in Oregon and Washington.
The project represents more than 200 person years of development by Intel’s China Software Center in Shanghai, and Intel software labs in Oregon and Washington.
https://www.intel.com/pressroom/archive/releases/2004/20040601corp_a.htm
Indeed, much of Tiano’s initial code was born in Shanghai. In a sense, the Tiano project was one of Intel’s earliest renowned projects conducted in Shanghai. When I joined Intel in 2003, many colleagues were still working on the Tiano project.
The Tiano project was successful; it rebuilt the framework and core logic of the firmware layer using C++, constructing a software skyscraper in the firmware domain that utilized the technologies, ideas, and characteristics of the new century. The advanced interface concept made it fully modular, very easy to maintain and extend.
Looking back at history, the heavily invested Itanium project was not successful and gradually faded into oblivion. However, the Tiano project that paved the way for Itanium was very successful, possessing lasting vitality, and expanding its territory with the development of the times. It has not only become a characteristic technology of the X86 platform, serving today’s X86 desktops and servers, but has also extended to the ARM platform, delivering the essence of X86 technology to the ever-changing ARM platform.

Experiencing UEFI on RK3588

Purchasing the Yulan notebook allows you to become a member of LanShe, growing together with many technical experts.
For purchase, please visit the GeYou shop on Taobao:
https://m.tb.cn/h.Uuv7fit?tk=N1iIdn8t4CI


Shengge Academy is a knowledge-sharing platform under GeDu Technology, following the educational philosophy of “GeWu ZhiZhi” (to investigate things and acquire knowledge).
In the spirit of preserving ancient wisdom, Shengge Academy strives to closely integrate the essence of traditional culture with modern technology, using traditional culture and humanistic feelings to explain modern technology, and using modern technology to spread traditional culture.
Access Methods
Mobile: Search for “Shengge Academy” in WeChat Mini Programs
PC: Download Nano Code Community Edition Client
https://nanocode.cn/#/download

GeYou WeChat Official Account

Shengge Academy Mini Program

People who like this content also like
Issues harder to debug than memory being stomped on

Understanding RK3588 and LINUX 5.10 under the debugger

Compiler, what are you saying?

Review of the 2023 Hangzhou Study Class

Swipe left and right to view the next article