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