DavidBuchanan314 / rabbit_r1_boot_notes

Documenting the boot process of the Rabbit R1 (MediaTek mt6765, k65v1_64_bsp, Android 13)
MIT License
32 stars 4 forks source link

Rabbit R1 Boot Notes

REing/documenting the boot process of the Rabbit R1 (MediaTek mt6765, k65v1_64_bsp, Android 13 AOSP).

A lot of the information here will be generic to other Android and/or MediaTek devices, but my intention is only to document the specifics of the R1 device.

This is a living document.

Glossary

There are soooo many acronyms and abbreviations, so here's a big list for reference:

More terms defined here

Boot Stages Overview

Boot starts in brom, which is baked into the CPU silicon. The CPU starts in AArch32 mode.

The next stage is the Preloader, which is stored in the boot0 partition of eMMC (not to be confused with the boot GPT partition).

Preloader is loaded into SRAM at offset 0x200f10, with entrypoint at 0x201000. The CPU is still in AArch32 mode here.

The Preloader's stack spans from 0x200000 to 0x200c00.

The Preloader is responsible for showing the initial boot logo, charging animations, etc. (logo image data is stored in the logo GPT partition).

The Preloader loads cached DRAM calibration data from the boot_para GPT partition.

The Preloader loads the lk, tee (ATF), and gz GPT partitions into DRAM, and verifies their signatures.

ATF is loaded at 0x4800_0000, which is also where its entrypoint is. Once ATF has initialised, it jumps to GZ in EL2 context. (wrong, LK is loaded at 0x4800_0000, it seems that the LK entrypoint is responsible for calling ATF, which in turn calls GZ? Not really sure...)

GZ entrypoint is at 0x2_4780_0000 (which makes little sense, since that's outside of the DRAM range???)

GZ appears to be itself based on LK also ("welcome to lk/MP" in uart logs)

(TODO: move some of this "overview" stuff into the subsections below)

BROM

The CPU starts in AArch32 mode.

As far as I can tell, the ROM itself is mapped at address 0.

Among the first things it does is:

Preloader

The Preloader also starts in AArch32 mode.

The Preloader is responsible for (in no particular order):

LK

LK implements Android Verified Boot 2.0.

[In]secure Boot

(NOTE: This section is very WIP and may contain inaccurate information. I'll try to verify this stuff soon)

Bootloader lock status is stored in the seccfg partition. (i.e. whether Preloader will allow custom boot images to boot).

The format of this data is "SecCfgV4", and you can see the parsing logic implemented in mtkclient here (nb, it's the hwtype = "V2" codepath that gets followed).

The configuration data is hashed, and that hash is encrypted using a hardware crypto engine (sej). The encrypted hash acts as a signature of sorts.

As a security control this is ineffective for two reasons:

  1. IIUC, The "kamakiri" exploit allows for key dumping (since it gains code exec in brom context).
  2. IIUC, the DA can be asked nicely to encrypt/decrypt arbitrary data (no exploits needed!!!)

Physical Memory Map

start       - end (inclusive)

0x0000_0000 - 0x????_????: BROM

0x0010_0000 - 0x0011_2000: SRAM
0x0020_0000 - 0x0030_0000: SRAM (1MB)

0x1000_7000 - 0x????_????: WDT

0x1100_2000 - 0x1100_2020: UART
0x1100_3000 - 0x1100_3020: UART

0x4000_0000 - 0x1_4000_0000: DRAM (4GB)

Goals / TODOs

References