Announcing a tool for Armada 3720 firmware
Marek Behun
marek.behun at nic.cz
Mon Jun 14 17:11:56 CEST 2021
Hello,
this is announcement of mox-imager [1], a firmware uploader / manipulator
for Marvell's Armada 3720 SOC.
For most of you who use the SOC on boards other than Turris MOX, the
most useful feature probably is that it can upload a firmware via UART
at higher baudrates than Marvell's original WtpDownloader, which is
useful when debugging or during board manufacture.
Features that should be interesting for you:
- ability to upload firmware over UART at baudrates up to 6 MBaud.
This was tested on ESPRESSObin, but should also work on other boards
(uDPU, ESPRESSObin Ultra)
Uploading at 3 MBaud:
$ ./mox-imager -b 3000000 -D /dev/ttyUSB0 flash-image.bin
- ability to upload flash-image.bin firmware over UART
When TF-A builds for A3720, it creates image for SPI/eMMC called
flash-image.bin, and a directory uart-images containing 3 binaries
that you have to use instead of flash-image.bin if you want to boot
via UART.
mox-imager can work with both methods. When given flash-image.bin,
it updates BootFlashSign in the TIM header so that the BootROM will
accept the image when given over UART.
So both of these work:
$ ./mox-imager -D /dev/ttyUSB0 flash-image.bin
$ ./mox-imager -D /dev/ttyUSB0 TIM_ATF.bin wtmi_h.bin boot-image_h.bin
(This of course does not work if the image needs to be signed
cryptographically and the singing key is not present. But AFAIK only
Turris MOX uses this feature of the SOC.)
- mox-imager has an implementation of a mini-terminal (code from
U-Boot's kwboot), which can be used instead of minicom/kermit, once
the firmware is uploaded. Although this mini-terminal does not support
uploading images over Y-MODEM or other protocols to U-Boot, it can
still be useful. If not for anything else, then at least for the
ability to not lose any output which the SOC might have sent over
UART. (When using minicom/kermit, there is a small window when the
/dev/ttyX device is closed and some output is lost.) Use the -t flag
to invoke this mini-terminal.
Other features that we use on Turris MOX and may be useful to you, but
need implementation for your boards:
- we use one firmware image for all versions of our board:
DDR3 512 MiB, DDR3 1024 MiB, DDR4
This simplifies development of updates significantly.
We achieve this by burning board version info into the SOC's OTP.
The GPP code contained in the TIM header can read OTP and decide how
to initialize clock and DDR registers depending on the values there.
The GPP code also works when OTP is empty. In that case it first tries
to initialize the registers for DDR3, tests if DDR works, and if not,
switches to DDR4. Then it determines RAM size. Note that we do not use
this method in production, this was only tested on a few boards that
we use for development. (We do not know for example, whether it is
safe for the DDR4 chip if we first try to communicate with it in DDR3
mode, since the protocols are different.)
You can look at the GPP code at
https://gitlab.nic.cz/turris/mox-imager/-/blob/master/gpp/ddr.gpp
- mox-imager can create trusted firmware image signed with ECDSA
signature and can write the SOC's OTP so that only images signed
with a specific ECDSA key will boot. We use this on Turris MOX.
Related software:
- we have significantly modified Marvell's original WTMI firmware that
runs on the Cortex-M3 secure coprocessor. You can look at this
modified firmware at our mox-boot-builder repository [2] in directory
wtmi.
Perhaps the most interesting feature for you is that this firmware
exposes the SOC's internal HW RNG via the mailbox to Linux, and that
upstream Linux has a driver (turris-mox-rwtm) that registers this
random number generator via Linux' crypto API.
Another feature our firmware supports is that it can utilize the
crypto engine in the secure processor for creating ECDSA signatures.
Every Turris MOX has an ECDSA key generated and burned into OTP when
manufactured. When done correctly, it is impossible to read this key.
It is only possible to use it via the crypto engine for ECDSA
signatures. (The firmware has to be in trusted mode for this. If the
user has the ability to upload any firmware into their device, they
can read the private key from OTP.)
This firmware can be built as a standalone replacement of Marvell's
WTMI firmware from A3700-utils-marvell repository, but also as an
wtmi_app.bin payload application for Marvell's firmware (in this case
DDR and clocks are initialized by Marvell's code and HW RNG is
provided by wtmi_app.bin).
There are instructions on how to use this firmware on ESPRESSObin in
mox-boot-builder's README.md.
- turris-mox-rwtm driver in Linux [3] communicates with our WTMI
firmware (see the point above) and exposes to Linux:
- the SOC's HWRNG
- the SOC's ECDSA signing engine with singing key stored in OTP.
This can be used for authorizing the device, for example via SSH
- OTP rows containing Turris MOX' serial number, board version and
MAC address
I'm thinking about implementing code into this driver so that it will
also work with Marvell's original firmware, which only exposes access
to OTP memory.
- mox-pkcs11 [4] is a plugin for ssh that can utilize the HW ECDSA
signing mechanism mentioned above when connecting to an ssh server
Let us know if you are interested in any of these or need help with
something.
Marek & Pali
[1] https://gitlab.nic.cz/turris/mox-imager
The name should probably be something like a3720-tool, but
I called it mox-imager at the beginning because then it was meant
to be used only for Turris MOX.
[2] https://gitlab.nic.cz/turris/mox-boot-builder
[3] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/firmware/turris-mox-rwtm.c
[4] https://gitlab.nic.cz/turris/mox-pkcs11
More information about the U-Boot
mailing list