MediaTek details: Partitions and Preloader
NOTE: This is a continuation of the previous article in the series. The information was obtained from various sources and through reverse engineering, don’t take it as a reference!
UPDATE 03.07.2015: Add Download Agent references.
After the Boot ROM has completed the initialization of the core hardware, it loads the first block from the eMMC flash into the On-chip SRAM and starts execution. Usually this would be the location of the operating system bootloader firmware, but on MediaTek SoCs it usually isn’t. There’s an intermediate step: the Preloader. It is a piece of software that abstracts a bit between the platform and the actual bootloader, and it offers some additional features like the ability to boot from either MMC or NAND Flash or to read/write various parts of the flash via USB.
Overview
When MediaTek ships a kernel source package to a manufacturer, the package also contains the source code for the Preloader. Depending on the changes the manufacturer makes, the Preloader does slighlty different things on different SoCs and boards, so it’s not easy to come up with a generic description that fits all systems.
The following analysis is based on the ThunderKernel source code for the MT6582 SoC. The distribution is made up of the following parts:
- A platform-specific part in
mediatek/platform/${platform}/preloader
, this contains most of the code. - A custom (manufacturer-specific) part in
mediatek/custom/${platform}/preloader
. - A device-specific part in
mediatek/custom/${DEVICE}/preloader
.
Now let’s analyse the code.
CPU Init
When the preloader starts, the SoC has not yet been fully initialised and many things are in a random state. A piece of assembler code in mediatek/platform/${platform}/preloader/src/init/init.s
performs the following steps to create a clean state:
- Clear all registers.
- Switch to the SVC32 privileged mode.
- Disable interrupts.
- Set up the caches and some other, minor details (e.g. the stack).
- Jump to the
main
method in the C code.
Now execution continues in mediatek/platform/${platform}/preloader/src/core/main.c
, which calls a lot of other methods, which again call a lot of other methods. It makes no sense to disect every line of code in this article, so I’ll just give a high-level view of what’s happening and explain some details where necessary.
Platform init
The Preloader relies on some peripherials, so it has to initialize them. This is mostly done in the platform_pre_init
and platform_init
methods. The list of peripherials contains the timer, the PLL clock, the DDR memory controller, the Watchdog, the GPIO pins, the UART, the USB 1.1 port and the power management circuit.
There is something special here: after the flash storage has been initialised, the Preloader offers an early “emergency download” mode. The manufacturer can define a hardware key, which, when pressed during Preloader platform init, immediately reboots back into the Boot ROM and waits for a download.
At this point the Preloader also records the reason why the system was booted:
Partitions
After bringing up the platform, the preloader has full access to the internal storage. MediaTek decided to partition the storage, but the partition table is hardcoded. It is generated during Preloader generation from an Excel file (yes, really) in mediatek/build/tools/ptgen/${platform}/partition_table_${platform}.xls
by the command ./makeMtk -t ${device} ptgen
(here is an example for the bq Aquaris E4.5 Ubuntu Edition):
The generated partition table structure is stored in out/target/product/krillin/obj/PRELOADER_OBJ/cust_part.c
and looks like this (example for the bq Aquaris E4.5 Ubuntu Edition):
First Secure Boot stage
After loading all the partitions (and if the feature is enabled), the Preloader initialises the SecLib subsystem. The device vendor supplies an RSA key of up to 2048 bits in length (although the keys I’ve seen are only 1024 bits).
What SecLib does exactly is unknown. It takes configuration data from the SECURE partition (if it exists) and the RSA key, then calls into the binary blob mediatek/platform/${platform}/preloader/src/SecLib.a
.
Boot mode selection
After (optionally) confirming secure boot, the Preloader decides which boot mode to use.
NORMAL_BOOT
will be used if secure boot is disabled or the secure boot module doesn’t say otherwise. If Download Mode is enabled, this mode will immediately try to enter it.
There is a long list of other possible boot modes, and not all of them are self-explanatory:
Download mode
Before Download mode can be entered, the Preloader has to find out if a host is connected via USB or UART and running the MTK SP Flash Tool. It does this by configuring a virtual CDC ACM discipline on USB, so both lines are in fact serial ports and behave similarly.
The USB port will assume that the tool is connected if it receives a “set line coding” (configures baudrate etc.) CDC message. It then sends the string READY
to the tool and waits for the reception of a token of eight bytes.
After successful detection, the tool can send the special Start
command sequence (0xa0 0x0a 0x50 0x05
) to enter a special mode that is only available via USB. It interprets the following commands (I left the ones marked with “legacy” out):
Command | Command byte | Function |
---|---|---|
CMD_GET_BL_VER |
0xfe | Get Preloader version (seems to be always “1”) |
CMD_GET_HW_SW_VER |
0xfc | Return hardware subcode, hardware version and software version |
CMD_GET_HW_CODE |
0xfd | Return hardware code and status |
CMD_SEND_DA |
0xd7 | Send a special “Download Agent” binary to the SoC, signed with a key. |
CMD_JUMP_DA |
0xd5 | Set boot mode to DOWNLOAD_BOOT and start execution of the Download Agent sent in the previous step. |
CMD_GET_TARGET_CONFIG |
0xd8 | Get supported Preloader configuration flags |
CMD_READ16 |
0xa2 | Read data from the SoC memory (16 bit length parameter) |
CMD_WRITE16 |
0xd2 | Write data into SoC memory (16 bit length parameter) |
CMD_READ32 |
0xd1 | Read data from the SoC memory (32 bit length parameter) |
CMD_WRITE32 |
0xd4 | Write data into SoC memory (32 bit length parameter) |
CMD_PWR_INIT |
0xc4 | Initialise the power management controller (effectively a null op because it is already on) |
CMD_PWR_DEINIT |
0xc5 | Shut down the power management controller (effectively a null o) |
CMD_PWR_READ16 |
0xc6 | Read 16 bits of data from the power management controller interface memory |
CMD_PWR_WRITE16 |
0xc7 | Write 16 bits of data to the power management controller interface memory |
The Download Agent step is necessary because this way the Flash Tool can always send a current version for the exact hardware version that’s being used.
The UART has no possibility to detect if the physical line is powered, so it just sends the string READY
and hopes that it gets an eight byte token back. If it does, it assumes that the tool is present.
Note that the special commands from the table above are not available when communicating over the UART, probably because the Boot ROM already offers most of these commands via UART.
If the special Start
command is not issued by the host via USB, the Preloader enters a common mode in which it accepts the following commands over both USB and UART:
Command | Command string | Function |
---|---|---|
SWITCH_MD_REQ |
SWITCHMD |
Is probably supposed to switch the modem into firmware download mode, but doesn’t seem to do anything on the MT6582? |
ATCMD_NBOOT_REQ |
AT+NBOOT |
Switch to NORMAL_BOOT mode |
META_STR_REQ |
METAMETA |
Switch to META_BOOT mode |
FACTORY_STR_REQ |
FACTFACT |
Switch to FACTORY_BOOT mode |
META_ADV_REQ |
ADVEMETA |
Switch to ADVMETA_BOOT mode |
ATE_STR_REQ |
FACTORYM |
Switch to ATE_FACTORY_BOOT mode |
FB_STR_ACK |
FASTBOOT |
Switch to FASTBOOT mode |
Second Secure Boot stage
Again it is unknown that SecLib does at this stage, it calls into the binary blob most of the time.
The following (questionable) information was obtained by looking at the C wrapper and dumping the library symbols and strings:
- The security data comes from the
SECSTATIC
partition - Validation of cryptographic image signatures using RSA/SHA1
- The
UBOOT
,LOGO
,BOOTIMG
,RECOVERY
andANDROID
partitions seem to be checked at some point - The “customer name” seems to be checked somehow, but why?
The necessary signed images are most likely generated by the SignTool
binaries in mediatek/build/tools/SignTool
.
The device manufacturer can add additional security measures.
Load core boot images
Now that the Preloader knows that the system is safe and secure, it can go and load the firmware images from the internal flash.
This is a highly specialised process, because every image has to be processed differently. For example the firmware for the HSPA modem in the MT6582 has to be fed into the modem using special registers and commands, while the u-Boot boot loader can just be copied to the right memory address. In this step the Preloader will also decide which is the next component that gets executed after itself ends. By default this will be the image stored in the UBOOT
partition.
Note that in this step only the most basic firmware is loaded, this is usually just the modem and the bootloader.
Platform post init
In this step the platform is put into a defined state for the next boot process component (bootloader, Little Kernel). The most important step is to pass on the boot arguments that were set during Preloader execution. This will hopefully make more sense once we look at what happens after the Preloader, the whole MediaTek design is a bit complicated.
The boot argument structure on the MT6852 looks like this:
It is put at a defined memory location, where it “survives” until the next component grabs it.
Boot the next component
The last Preloader step is to jump to the location of the next component, usually the “Little Kernel” loaded from the UBOOT
partition.
If you know better and/or something has changed, please find me on Launchpad.net or the Freenode IRC and do get in contact!
Again a good and useful job, thanks for publishing !
Yes, I can confirm that SignTool is able to add digital signature information to firmware images. Signed images have an additional header “BFBF” and some fluff which SP Flash Tool checks on a secure device. Apparently some manufacturers merely used the default MTK key for signing the images, making them no better off than a typical insecure MTK device.
So if we are talking about “unlock bootloader”, here on Mediatek it is unlock Preloader. if i see it right.
Is it possible to disable the Signed-key check, thus unlocking, by modding the preloader?
Yes, in theory.
Not just a theory anymore.
No more bricked Mediatek devices.
This genius used the Download Mode [DL] described above as part of his master work.
See here the achievements:
https://forum.xda-developers.com/hd8-hd10/orig-development/fire-hd-8-2018-downgrade-unlock-root-t3894256/page6#post78782461
I need some help.
I just hard bricked my gionee a1 lite while flashing in sp flashtool.
Mistake i did : Unfortunately added the preloader file when trying to install TWRP.
As result my phone is completely hard bricked (ie., not turning on, not even bootloop, no charging logo, and not detected by PC when holding Volume UP button.
Is there any solution ?
Can anyone help me ?
In this case you would most likely have to desolder the flash and program it with an external programmer.
Hey, could You give me any tips regarding DA? My phone is bricked, so I was searching for solution. For now I have successfully performed “handshake” and now I’m testing some commands. Write command doesn’t really have permissions for writing in boot.img range (my guess). So now I’m trying to reverse DA for my device to load it and (not sure) flash correct boot.img? One more question: Is there any dedicated command to enter fastboot mode besides this one in article?
hey guys i really need help my vfd1100 is stuck on bootanimation i have flashed a new stock rom situation is still the same {this was caused by link2sd card app i tried to reboot my phone to recovery using this app and then this happed} i also performed factory reset also nothing changes please help me.
Pingback: Can I flash Android on device with overwritten mmcblk0?