Flashing firmware on DaVinci media processors - o-gs/dji-firmware-tools Wiki

Table of Contents

Overview
Flashing via serial port
  Flashing u-boot by serial port
  Flashing kernel
  Flashing encrypted partition
  Flashing Root Filesystem
  Fix FPV restricted to 8 fps

Overview

Several DJI products use DM3xx family DaVinci media processors from Texas Instruments. Since the NAND memory chips which DJI uses to store their firmware can often stop working or lose data after several months without powering on, there is sometimes a need to re-flash part of the firmware, or even replace the chip and re-flash all partitions of the firmware. This page will explain the procedure.

Replacing whole NAND chip

When going the chip replacement route, you may first check whether some data can be still salvaged from the board. There are some files on the NAND which are unique to every drone, and can't be completely recovered when lost. Read the info on 8 fps issue for details.

Flashing via serial port

It is possible to boot the chip into a mode which allows programming it via serial port. Since the board requires 3.3V serial interface, you will need USB to TTL converter (aka FTDI adapter) which supports this voltage.

Connect your 3.3V TTL converter to service pads. While this depends on markings of specific TTL converter, usually RX should be connected to TX and vice versa. Don't worry about connecting RX and TX incorrectly, switching them will not damage anything, it just won't work. The pad names depend on the board you have:

If your TTL converter has a 5V power output, you may also choose to power your board from it, completely disconnecting it from aircraft. Be careful with that - connecting power from the drone and from TTL at the same time may overheat and damage some of the components. If you want to work on your board disconnected, connect power to a service pad marked 5V. The board will draw up to 700mA of current (over 1000 mA if it also contains Ambarella) - connecting it to low-power USB will cause random resets and transmission errors.

Flashing u-boot by serial port

If after tapping to the serial interface, you see no message, or booting does not get to loading kernel, then you should re-flash u-boot images. When u-boot is good, it will display the message Loading from nand0, offset 0x??????.

To re-flash u-boot, you should boot the chip into a mode which allows programming it via serial port.

To switch the boot mode, short the Boot Select service pad to 3.3V. Marking of Boot Select pad depends on board:

After the pad is connected, use TI utilities on connected PC to flash your new image:

If you typed the correct port name, and service pads are shorted properly, you should see Target: BOOTME message. You have to press Ctrl+C to get back to a prompt, and then run the command again. The second time it will work, resulting in message Operation completed successfully.. Example for full log from the flashing:

You will need the unencrypted images of TI DaVinci Linux and the U-boot bootloader to do the flashing - files ubl1.img and u-boot.img. Depending on the board you're fixing, these are stored in appropriate modules within firmware update:

Download the correct firmware package, and extract it with the tools provided within dji-firmware-tools repository.

For more sources of information, you can look at the description of the flashing procedure for Lightbridge for some details. There is also a P3X-specific tutorial for Gimbal Top board, created by SunsetCatcher; you should be able to find links to his ph3pns.zip archive on PhantomPilots.

TI Serial Flashing tool

This method is based on Serial Boot and Flash Loading Utility provided by Texas Instruments. See "Obtaining the software" and "Versions for Other Devices" chapters of that page to download a version for the correct processor series.

Flashing kernel

If at the serial interface you see kernel boot error, or Recovery Kernel is booted, or kernel stops booting - you should reflash the kernel image. For example, this is how booting Recovery Kernel looks like:

If both primary and recovery kernel is corrupted, the booting will end at U-Boot command line:

Note that u-boot tries to load primary kernel after message Loading from nand0, offset 0x4a0000, and recovery kernel is tried only if primary failed, with message Loading from nand0, offset 0x900000. The offsets at which kernel images are located inside NAND, depend on memory map used within specific product - see pages about your module ([m0800](/o-gs/dji-firmware-tools/wiki/Firmware m0800#structure)/[m1300](/o-gs/dji-firmware-tools/wiki/Firmware m1300#structure)/[m1301](/o-gs/dji-firmware-tools/wiki/Firmware m1301#structure)) for proper memory map. There are some products which do not have recovery kernel, and there is only one kernel. For these platforms, u-boot will only show one message about Loading from nand0.

Usually you will want to flash the primary kernel, uImage. For most boards, you can get it from firmware update (see chapter about flashing bootloader for firmware module marking). For specific boards:

If your Recovery Kernel is also damaged, you may also flash the special recovery image uImage_recovery. It is not a part of firmware update, so you need to find a proper image:

It might be better to use the primary kernel image to flash both copies of kernel. The Recovery Kernel is different only because it is never updated automatically by DJI firmware updates - it stays as it was when going out of factory. This means the Recovery Kernel is just a very old version of the ordinary kernel.

Preparations

To reflash the kernel, you need to press the ESC key just when your board gets power, so that you end up in u-boot console. Next press Enter to get rid of any additional ESC stokes left in input buffer:

Now, you need to load a new kernel image to DRAM, and from there, flash it to NAND memory.

Let's start by cleaning a portion of DRAM which we will use:

Next we need to put our kernel image into that location. There are two ways:

Loading kernel via serial using ModemY

The transfer over serial is very slow and cumbersome. It requires compatible terminal client. On Windows, you can use ExtraPuTTY. On Linux, Minicom can support it.

First, initiate the transfer on DaVinci side:

Then, use proper function in your terminal to select the target file. The transfer will last some time - for 4MB kernel, it should take around 13 minutes. After it finishes, you will see:

Loading kernel via USB stick

This is the method I'd suggest. It is fast and reliable, especially for boards which by design have USB connector linked to the DaVinci chip. On some boards, the USB output comes from Ambarella - in such case, using the DaVinci USB requires manually soldering a female USB connector to proper pins. The method was tested with 2GB sd-card formatted to FAT32 and inserted into USB Card Reader. Some USB sticks were not detected by the DM3xx USB controller - it is best to try a few of them.

If your board does not have USB connector to DaVinci, you'll have to solder it:

wire color solder point
Vbus red 5V service pad
GND black GND service pad
D+ green Gimbal-to-OFDM ribbon cable pin1
D- white Gimbal-to-OFDM ribbon cable pin2

In some of the gimbal boards, USB is controlled by GPIO pin of the DM3xx chip; if usb start shows no information about USB device connected, then it may be required to switch the proper GPIO pin by software. It is not fully known how to do this, or which of GPIO pins is used. If USB just doesn't want to work on your board, use serial transfer instead.

Copy the kernel image on your USB stick, and put it into USB slot of your board. Then, execute the following:

The second command isn't really needed, but it will show you your USB device, so that you know it is functioning. Now, start the loading process:

On success, you should see something like:

Flashing the kernel from DRAM

Be careful, you are now going to make changes to your NAND memory. Do not lose or add any zeros in the offsets. Select one of the following chapters, based on memory map used in your device. DaVinci modules in most products use the [typical memory map](/o-gs/dji-firmware-tools/wiki/Firmware m1300#structure).

Flashing the kernel from DRAM on typical NAND memory map

To write Primary Kernel, execute the following commands:

In case you are writing Recovery Kernel, run the commands below instead:

You can write the same kernel image over the two locations. But if the recovery kernel works, there is no reason to overwrite it.

Flashing the kernel from DRAM on FC200

The first use of DM36x by Dji, FC200 camera from P2V, has a bit different memory map and requires different addresses; kernel is also compressed there, and therefore smaller:

In case you are writing Recovery Kernel, run the commands below instead:

You can write the same kernel image over the two locations. But if the recovery kernel works, there is no reason to overwrite it.

Flashing the kernel from DRAM on RC001

The [memory map](/o-gs/dji-firmware-tools/wiki/Firmware m1301#structure) within Inspire 2 RC has a different layout; kernel is usually smaller, but there is no reason not to rewrite the whole partition:

There is no recovery kernel partition for this product, so that is all.

Flashing encrypted partition

If the encrypted partition gets damaged, Linux will stop booting - kernel module responsible for encryption will freeze. In such case, the system freezes soon after the message:

If this happens, you may want to reflash this partition. It is not a part of firmware update, so you need to find a proper image:

Note: this partition is different for every specific board instance; do not reflash it unless you are having issues you know are related to it! Some products (P2 series, Inspire RC001) do not have that partition at all.

The procedure is almost the same as for flashing kernel, so it will not be explained in detail. Commands:

Flashing Root Filesystem

The Ubi File System is able to correct its errors and mark would-be bad sectors in advance, so it is unusual for it to get corrupted. It is also the hardest component to recover. Do not flash the UbiFS unless error messages explicitly say it is damaged!

The UbiFS partitions cannot be just written by nand write as all the others, because it contains EC blocks supported by NAND hardware. Writing them this way would make them possible to read only once, after that EC block would be damaged.

While u-boot has UbiFS support, it is unfinished in the old version provided in firmwares. Do not use it - it will damage your UbiFS even further.

The only viable option is to flash the new UbiFS image from Linux. To run Linux independently of the UbiFS Root Filesystem, we will need another root - Recovery Root Filesystem. It needs to be as small as possible, but still have all the tools required to work with UBI partitions. You can get it here.

Getting a Root Filesystem image

You will need a valid UbiFS Root Filesystem image, the one we want to recover. It is not a part of firmware update, so you need to find one:

Keep the image handy - we will need it after we'll manage to boot Linux.

Flashing Recovery Root Filesystem

Since we have no unused space on the disk to fit our partition, we will have to temporarily sacrifice something else. For most boards, the best candidate is our primary kernel - it will be easy to recover it later, and it is far from encrypted partition which we don't want to accidentally overwrite.

If you don't understand the commands, or want to use serial instead of USB, read flashing kernel section.

Flashing Recovery Root Filesystem on typical NAND memory map

We will now overwrite the primary kernel with our Recovery Root Filesystem.

To load the Recovery Root FS, insert USB stick with the partition image, boot to u-boot Console and execute:

That will place the Recovery Root FS image in DRAM (you may also do the same using serial transfer). Next, you want to flash it, sacrificing primary kernel:

That's it - now we should be able to boot. Read Booting to Linux chapter below.

Flashing Recovery Root Filesystem on FC200

For FC200 camera from P2V, with its specific memory map, flashing Recovery Root Filesystem will overwrite both kernels. We will have to deal with that.

To load the Recovery Root FS, insert USB stick with the partition image, boot to u-boot Console and execute:

That will place the Recovery Root FS image in DRAM (you may also do the same using serial transfer). Next, you want to flash it, sacrificing both kernels:

Now you have no valid kernel on the NAND. So to boot Linux, you need to write a third kernel somewhere further, I'd suggest just after the Recovery Root FS, at 0x0a80000. To load and flash the kernel, execute:

For more info on these commands, see chapter on Flashing kernel.

After the kernel is flashed, we should be able to boot. Read Booting to Linux chapter below.

Flashing Recovery Root Filesystem on RC001

If you are fixing Inspire 2 RC board, there is no recovery kernel - only primary. But the place for kernel is large enough to store Recovery Root FS, and we also have the logo partition which is empty, so there is a way to fit both the kernel and the Recovery Root FS on the NAND:

To load the Recovery Root FS, insert USB stick with the partition image, boot to u-boot Console and execute:

That will place the Recovery Root FS image in DRAM (you may also do the same using serial transfer). Next, you want to flash it, sacrificing the kernel:

Now you have no valid kernel on the NAND. So to boot Linux, you need to overwrite U-boot logo at 0x0280000. To load and flash the kernel, execute:

For more info on these commands, see chapter on Flashing kernel.

After the kernel is flashed, we should be able to boot. Read Booting to Linux chapter below.

Booting to Linux with Recovery Root FS

Now we are able to boot our Recovery Kernel, pointing it to our Primary Kernel partition for Root Filesystem location. But if started normally, the u-boot would set the kernel parameters so that they point to original Root Filesystem. We need to land in U-boot console, and there change the Root Filesystem location in kernel parameters before starting the kernel.

Booting with Recovery Root FS on typical NAND memory map

To start recovery kernel with rootfs placed on primary kernel partition, boot to u-boot Console and execute:

Booting with Recovery Root FS on FC200

To start your third kernel with rootfs placed on primary kernel partition, boot to u-boot Console and execute:

Booting with Recovery Root FS on RC001

To start your kernel from U-boot logo partiton with rootfs placed on kernel partition, boot to u-boot Console and execute:

The actual Root Filesystem flash operation

When the Linux is started with different rootfs, you can format the UbiFS partition with new image. The commands below assume that UbiFS partition is visible as mtd2 - make sure it is the case before executing the commands:

If you do not have USB connector to read the image from, you can use ramdisk (/tmp) to temporarily store an image transferred by serial. In such case, use lrz tool available in the Recovery Root Filesystem to receive binary ymodem transmission.

To check whether the filesystem is functional, try:

If this resulted in details on file system blocks and no error information, UbiFS is restored! Now, booting from Recovery Kernel should work without using our Recovery Root Filesystem. Restart the board; since the Primary Kernel does not contain a valid Kernel, u-boot will boot Recovery kernel automatically.

If the Linux system boots properly, we can restore the Primary Kernel to finish the process. Follow the instructions above to do that.

Fix FPV restricted to 8 fps

When Encrypted Partition or Root Filesystem are re-flashed, the First Person View Video on Mobile Device will come back but only at 8 frames per second. This chapter will focus on explaining and providing a fix for this issue.

Modules [m0100](/o-gs/dji-firmware-tools/wiki/Firmware m0100) (Ambarella App), [m0800](/o-gs/dji-firmware-tools/wiki/Firmware m0800) (DaVinci Processor) and [m0400](/o-gs/dji-firmware-tools/wiki/Firmware m0400) (Gimbal Controller) share access to ATSHA204 chip, which provides safe storage for a cryptographic key. Using that chip, these modules can encrypt data in a way which is hard to break - because there is no way to extract key from ATSHA204. They do not use the key from ATSHA204 directly - instead, it is used to store another key within persistent storage of each of the modules, and they are stored in encrypted form.

In case of DaVinci Media Processor, there are two copies stored - one as the entire Encrypted Partition, and second as /etc/key.bin within the Root Filesystem. If these were damaged, they're not easy to recover.

The encryption capability is used at startup, to verify whether all modules share the same key. If that verification fails, DaVinci processor will continuously re-try encryption pairing, forever. Since encryption is computationally expensive, that will degrade FPV video to 8 fps.

As a side note - if that same verification fails in Ambarella App, the module will enter AuthorityLevel=0 mode. In this mode, it will ignore most commands. If your Ambarella works, but refuses to start recording or to take a photo - this might be the cause.

To fix the issue when the encryption keys were damaged, the best approach is to mod the firmware so that it will ignore encryption fail at startup. In case of DaVinci, encode_usb binary needs to be modified and copied back to the Root Filesystem. In case of Ambarella App, the sys partition needs to be modified. Modifications can be performed using *_hardcoder.py scripts from this repository. Some details are provided within these scripts.

Why we can't just pair these chips again, you ask? The factory pairing DUML command can be easily triggered on the gimbal, but it won't be able to update key within ATSHA204 chip - it was irreversibly sealed during first pairing. So to do the pairing again, you'd have to replace that chip. Without replacing it, the only way is to workaround the issue by fixing encode_usb.