TF-A, TBBR�open source bootloader for RPi3
PaulLiu (Ying-Chun Liu)�COSCUP 2019
About me
Reverse Engineering
案例 - WDL
et1009-tools
AnyX
RaspberryPi3
Raspbian boot partition
ARM Cortex-A53
VideoCore 4
Videocore 4
目前的 Memory Map
Boot code
dtb
kernel
Videocore 4
TF-A
Architecture
調整一下記憶體使用方式
BL1
dtb
kernel
FIP
BL2/BL31
BL32(OPTEE)
BL33(U-Boot)
修改 config.txt
Build u-boot
Build optee
make \
CROSS_COMPILE_ta_arm32=arm-linux-gnueabihf- \
CROSS_COMPILE_core=aarch64-linux-gnu- \
PLATFORM=rpi3 CFG_ARM64_core=y \
CFG_DT=y CFG_DT_ADDR=0x14000000 \
CFG_TEE_CORE_LOG_LEVEL=4 \
CFG_EXTERNAL_DTB_OVERLAY=y
Compile TF-A
env CROSS_COMPILE=aarch64-linux-gnu- make \
PLAT=rpi3 RPI3_BL33_IN_AARCH32=1 \
BL33=u-boot.bin NEED_BL32=yes \
BL32=tee-header_v2.bin \
BL32_EXTRA1=tee-pager_v2.bin \
BL32_EXTRA2=tee-pageable_v2.bin LOG_LEVEL=40 CRASH_REPORTING=1 \
GENERATE_COT=1 TRUSTED_BOARD_BOOT=1 \
USE_TBBR_DEFS=1 SPD=opteed MBEDTLS_DIR=../mbedtls \
RPI3_PRELOADED_DTB_BASE=0x01000000 \
RPI3_RUNTIME_UART=1 all
Boot log
NOTICE: Booting Trusted Firmware
NOTICE: BL1: v2.1(release):atf-pr1768-748-g17e93a8-dirty
NOTICE: BL1: Built : 15:04:14, Aug 7 2019
INFO: BL1: RAM 0x100ee000 - 0x100f9000
INFO: Using crypto library 'mbed TLS'
NOTICE: rpi3: Detected: Raspberry Pi 3 Model B (1GB, Embest, China) [0x00a22082]
INFO: BL1: Loading BL2
INFO: Loading image id=6 at address 0x100b4000
INFO: Image id=6 loaded: 0x100b4000 - 0x100b446f
INFO: Loading image id=1 at address 0x100b4000
INFO: Image id=1 loaded: 0x100b4000 - 0x100c75b0
NOTICE: BL1: Booting BL2
INFO: Entry point address = 0x100b4000
INFO: SPSR = 0x3c5
Boot log
NOTICE: BL2: v2.1(release):atf-pr1768-748-g17e93a8-dirty
NOTICE: BL2: Built : 15:04:09, Aug 7 2019
INFO: Using crypto library 'mbed TLS'
INFO: BL2: Doing platform setup
INFO: BL2: Loading image id 3
INFO: Loading image id=7 at address 0x100e0000
INFO: Image id=7 loaded: 0x100e0000 - 0x100e060e
INFO: Loading image id=9 at address 0x100e0000
INFO: Image id=9 loaded: 0x100e0000 - 0x100e04da
INFO: Loading image id=13 at address 0x100e0000
INFO: Image id=13 loaded: 0x100e0000 - 0x100e0430
INFO: Loading image id=3 at address 0x100e0000
INFO: Image id=3 loaded: 0x100e0000 - 0x100e8070
INFO: BL2: Loading image id 4
INFO: Loading image id=10 at address 0x10100000
INFO: Image id=10 loaded: 0x10100000 - 0x101004e8
INFO: Loading image id=14 at address 0x10100000
INFO: Image id=14 loaded: 0x10100000 - 0x101004ce
INFO: Loading image id=4 at address 0x10100000
INFO: Image id=4 loaded: 0x10100000 - 0x1010001c
Boot log
INFO: OPTEE ep=0x10100000
INFO: OPTEE header info:
INFO: magic=0x4554504f
INFO: version=0x2
INFO: arch=0x1
INFO: flags=0x0
INFO: nb_images=0x1
INFO: BL2: Loading image id 21
INFO: Loading image id=21 at address 0x10100000
INFO: Image id=21 loaded: 0x10100000 - 0x1014f370
INFO: BL2: Skip loading image id 22
INFO: BL2: Loading image id 5
INFO: Loading image id=11 at address 0x11000000
INFO: Image id=11 loaded: 0x11000000 - 0x110004ea
INFO: Loading image id=15 at address 0x11000000
INFO: Image id=15 loaded: 0x11000000 - 0x11000440
INFO: Loading image id=5 at address 0x11000000
INFO: Image id=5 loaded: 0x11000000 - 0x1107bae8
Boot log
INFO: BL33 will boot in Non-secure AArch32 Hypervisor mode
NOTICE: BL1: Booting BL31
INFO: Entry point address = 0x100e0000
INFO: SPSR = 0x3cd
NOTICE: BL31: v2.1(release):atf-pr1768-748-g17e93a8-dirty
NOTICE: BL31: Built : 15:04:12, Aug 7 2019
INFO: rpi3: Checking DTB...
INFO: rpi3: Reserved 0x10000000 - 0x10100000 in DTB
INFO: BL31: Initializing runtime services
INFO: BL31: Initializing BL32
INFO: BL31: Preparing for EL3 exit to normal world
INFO: Entry point address = 0x11000000
INFO: SPSR = 0x1da
Boot log
U-Boot 2019.01 (Aug 07 2019 - 07:43:43 +0000)
DRAM: 948 MiB
RPI 3 Model B (0xa22082)
MMC: mmc@7e202000: 0, sdhci@7e300000: 1
Loading Environment from FAT... *** Warning - bad CRC, using default environment
In: serial
Out: vidconsole
Err: vidconsole
Net: No ethernet found.
starting USB...
USB0: scanning bus 0 for devices... 3 USB Device(s) found
scanning usb for storage devices... 0 Storage Device(s) found
Hit any key to stop autoboot: 2
armstub8.bin 內容
BL1
FIP
$ ./tools/fiptool/fiptool info fip.bin
Trusted Boot Firmware BL2: offset=0x268, size=0x115B0, cmdline="--tb-fw"
EL3 Runtime Firmware BL31: offset=0x11818, size=0x7070, cmdline="--soc-fw"
Secure Payload BL32 (Trusted OS): offset=0x18888, size=0x1C, cmdline="--tos-fw"
Secure Payload BL32 Extra1 (Trusted OS Extra1): offset=0x188A4, size=0x4CC00, cmdline="--tos-fw-extra1"
Secure Payload BL32 Extra2 (Trusted OS Extra2): offset=0x654A4, size=0x0, cmdline="--tos-fw-extra2"
Non-Trusted Firmware BL33: offset=0x654A4, size=0x7C4B4, cmdline="--nt-fw"
Trusted key certificate: offset=0xE1958, size=0x60E, cmdline="--trusted-key-cert"
SoC Firmware key certificate: offset=0xE1F66, size=0x4DA, cmdline="--soc-fw-key-
cert"
Trusted OS Firmware key certificate: offset=0xE2440, size=0x4E8, cmdline="--tos-
fw-key-cert"
Non-Trusted Firmware key certificate: offset=0xE2928, size=0x4EA, cmdline="--nt-
fw-key-cert"
FIP
FIP(Cont)
ROT Key
Trusted world key
Non-Trusted world key
BL31 key
BL32 key
BL33 key
BL31 content hash
BL32 content hash
BL33 content hash
BL2 content hash
Trusted Boot?
Example: How BL2 verifies BL33
BL2
ROTPK_Hash
BL33 (U-boot)
BL33 content hash
BL33 key
Trusted world key
Non-Trusted world key
How BL1 verifies BL2?
BL2
ROTPK_Hash
BL1
ROTPK_Hash
BL2 content hash
Who verifies BL1??
BL1
ROTPK_Hash
BL1
FUSE
RaspberryPi3
Conclusion
VideoCore4 ?
vc4-toolchain
rpi-open-firmware
修改 rpi-open-firmware
修改 TF-A
修改後的 repository
Boot log
Booting Raspberry Pi....
Copyright 2016-2017 rpi-open-firmware authors
BUILDATE : Aug 17 2019 01:28:13
__cxx_init: calling 5 static constructors (0x14000 - 0x14014) ...
BCM2708UsbPhy::registerDriver(): driver registered on platform IO plane
BCM2708ArmControl::registerDriver(): driver registered on platform IO plane
BCM2708PLLB::init(): PLLB VCO registered
BCM2708PLLB::registerDriver(): driver registered on platform IO plane
BCM2708Gpio::registerDriver(): driver registered on platform IO plane
[SDRAM:sdram_init]: (0) SD_CS = 0x794200
[SDRAM:switch_to_cprman_clock]: switching sdram to cprman clock (src=1, div=1),
waiting for busy (4011) ...
[SDRAM:switch_to_cprman_clock]: busy set, switch complete!
[SDRAM:reset_phy]: reset_phy: resetting SDRAM PHY ...
[SDRAM:reset_phy]: reset_phy: resetting DPHY CTRL ...
[SDRAM:reset_phy_dll]: resetting aphy and dphy dlls ...
[SDRAM:reset_phy_dll]: waiting for dphy master dll to lock ...
[SDRAM:reset_phy_dll]: dphy master dll locked!
[SDRAM:sdram_init]: waiting for SDUP (210242) ...
Boot log
[SDRAM:sdram_init]: SDRAM controller has arrived! (218E42)
[SDRAM:calibrate_pvt_early]: DPHY_CSR_DQ_PAD_DRV_SLEW_CTRL = 0x223
[SDRAM:calibrate_pvt_early]: waiting for address PVT calibration ...
[SDRAM:calibrate_pvt_early]: waiting for data PVT calibration ...
[SDRAM:calibrate_pvt_early]: waiting for SDRAM calibration command ...
[SDRAM:sdram_init]: SDRAM Type: Elpida 1GB LPDDR2 (BC=0x58)
[SDRAM:reset_with_timing]: waiting for SDRAM controller to go down (218E4A) ...
[SDRAM:reset_with_timing]: SDRAM controller down!
[SDRAM:reset_with_timing]: SDRAM clock disabled!
[SDRAM:reset_with_timing]: waiting for master ddr pll to lock ...
[SDRAM:reset_with_timing]: master ddr pll locked!
[SDRAM:reset_with_timing]: SDRAM Addressing Mode: Bank=3 Row=3 Col=3 SB=0xFF
[SDRAM:reset_phy_dll]: resetting aphy and dphy dlls ...
[SDRAM:reset_phy_dll]: waiting for dphy master dll to lock ...
[SDRAM:reset_phy_dll]: dphy master dll locked!
[SDRAM:reset_with_timing]: waiting for address dll to lock ...
[SDRAM:reset_with_timing]: address dll locked!
[SDRAM:selftest]: Starting self test ...
Boot log
[SDRAM:selftest_at]: Testing region at 0xC0000000 ...
[SDRAM:selftest_at]: Testing region at 0xCFF00000 ...
[SDRAM:selftest_at]: Testing region at 0xDFF00000 ...
[SDRAM:selftest_at]: Testing region at 0xEFF00000 ...
[SDRAM:selftest_at]: Testing region at 0xFFF00000 ...
[SDRAM:selftest]: Self test successful!
SDRAM initialization completed successfully!
BCM2708PowerDomainUSB::stop(): stopping ...
BCM2708PowerDomainUSB::stop(): stopped
BCM2708PowerDomainImage::powerOn(): powering on, current PM_IMAGE state: 0x1000
BCM2708PowerDomainImage::beginPowerUpSequence(): starting power up sequence ...
BCM2708PowerDomainImage::waitForPOWOK(): waiting for POWOK ...
BCM2708PowerDomainImage::waitForPOWOK(): got POWOK with CFG=0x10000
BCM2708PowerDomainImage::powerOn(): stopping power up sequence ...
BCM2708PowerDomainImage::beginPowerUpSequence(): starting power up sequence ...
BCM2708PowerDomainImage::waitForPOWOK(): waiting for POWOK ...
BCM2708PowerDomainImage::waitForPOWOK(): got POWOK with CFG=0x30000
BCM2708PowerDomainImage::completePowerUpSequence(): waiting for MRDONE ...
Boot Log
BCM2708PowerDomainImage::resetPeripheralsUngated(): calling v16mov gated ...
BCM2708PowerDomainImage::resetPeripheralsUngated(): ungating and resetting ...
BCM2708PowerDomainImage::resetPeripheralsUngated(): done
BCM2708PowerDomainImage::start(): CM_PERIICTL = 0x40
BCM2708PowerDomainImage::start(): CM_PERIIDIV = 0x0
BCM2708PowerDomainImage::start(): PM_IMAGE = 0x3107F
BCM2708PowerDomainImage::start(): started
BCM2708PowerDomainUSB::start(): starting ...
BCM2708PowerDomainUSB::start(): started
BCM2708UsbPhy::start(): starting ...
BCM2708UsbPhy::start(): LAN reset
BCM2708UsbPhy::start(): started
BCM2708ArmControl::start(): starting ...
BCM2708ArmControl::loadInitialCode(): copied 57412 bytes to 0xC0000000!
BCM2708ArmControl::start(): original memstart: 0xEA000039
BCM2708ArmControl::start(): mapped VC 0xC0000000 to ARM 0x0
BCM2708ArmControl::start(): mapped peripherals VC 0x7E000000 to ARM 0x3F000000
BCM2708ArmControl::start(): ARM ID: 0x364D5241 C0: 0x0
BCM2708ArmControl::start(): using C0: 0xA24B
Boot log
BCM2708ArmControl::setupClock(): initializing PLLB ...
BCM2708PLLB::setDigValues(): setting DIG values for this VCO ...
BCM2708ArmControl::setupClock(): KAIP = 0x228
BCM2708ArmControl::setupClock(): MULTI = 0x613277
BCM2708ArmControl::setupClock(): ARM clock succesfully initialized!
BCM2708PowerDomainARM::start(): starting ...
BCM2708PowerDomainARM::powerOn(): powering on (rstnMask=0xFFFFFFBF) ...
BCM2708PowerDomainARM::beginPowerUpSequence(): starting power up sequence ...
BCM2708PowerDomainARM::waitForPOWOK(): waiting for POWOK ...
BCM2708PowerDomainARM::waitForPOWOK(): got POWOK with CFG=0x0
BCM2708PowerDomainARM::completePowerUpSequence(): waiting for MRDONE ...
BCM2708PowerDomainARM::powerOn(): domain powered on succesfully
BCM2708PowerDomainARM::start(): started
BCM2708ArmControl::bridgeStart(): setting up async bridge ...
BCM2708PowerDomainARM::setReset(): setting RSTN bits to 0x40 ...
BCM2708ArmControl::bridgeCycleBresp(): cycling through bresp bits ...
BCM2708PowerDomainARM::setReset(): setting RSTN bits to 0x40 ...
BCM2708ArmControl::bridgeStart(): starting async bridge now!
BCM2708ArmControl::bridgeStart(): bridge init done, PM_PROC is now: 0x107F!
Starting IPC monitor ...
TODO
New TODO
Q&A?