-
Notifications
You must be signed in to change notification settings - Fork 427
Flashing firmware on DaVinci media processors
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
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.
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:
- for Ph3 Pro Gimbal Top board, the names are
368_U0_RXP
,368_U0_TXP
andGND
. - for Inspire X5 Camera Live View Encoder board, the names are
RXP
,TXP
andGND
. - for GL300a Interface board (WM323_INTERFACE_V2 or P00928.??), the names are
UART0_RX
,UART0_TX
andGND
. - for GL300 HDMI board, the names are
368_RX
,368_TX
andGND
. - for Lightbridge Air Unit Encoder board, the names are
U_RX
,U_TX
andGND
. - for Lightbridge Ground Unit board, the names are
RXD
,TXD
andGND
. - for N1 Video Encoder board from Matrice 100, the names are
U0_RX
,U0_TX
andGND
. - for Ph2 Vision+ WiFi module and the WM301 Live View Encoder board, the names are
UART0_RX
,UART0_TX
andGND
is Ground. - for the FC200 Live View Encoder board inside egg camera of Ph2 Vision, the names are
TP2
(RX),TP1
(TX) andTP3
is Ground.
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.
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:
- for Ph3 Pro Gimbal Top board, you have to short two pads -
BT00
andBT01
. - for Inspire X5 Camera Live View Encoder board, the two pads are
BTSEL00
andBTSEL01
. - for GL300a Interface board (WM323_INTERFACE_V2 or P00928.??), the name is
BTSELV
. - for GL300 HDMI board, the name is
BTSEL
. - for Lightbridge Air Unit Encoder board, the name is
BSEL
, but markings are rarely printed. - for Lightbridge Ground Unit board, the name is
BSEL
. - for N1 Video Encoder board from Matrice 100, the name is
BTSEL00
. - for Ph2 Vision+ WiFi module and the WM301 Live View Encoder board, the name is
BOOT
. - for the FC200 Live View Encoder board inside egg camera of Ph2 Vision, there is no pad, but a specific resistor is connected to the boot select input of the chip.
After the pad is connected, use TI utilities on connected PC to flash your new image:
sfh_DM36x -nandflash -v -p "COM21" ubl1.img u-boot.img
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:
----------------------------------------------------- TI Serial Flasher Host Program for DM36x (C) 2009, Texas Instruments, Inc. ----------------------------------------------------- Flashing NAND with ubl1.img and u-boot.img. Attempting to connect to device com21... Waiting for the DM36x... Target: BOOTME BOOTME commmand received. Returning ACK and header... ACK command sent. Waiting for BEGIN command... Target: BEGIN BEGIN commmand received. Sending CRC table... CRC table sent.... Waiting for DONE... Target: DONE DONE received. Sending the UBL... UBL sent.... Target: DONE DONE received. UBL was accepted. UBL transmitted successfully. Waiting for SFT on the DM36x... Target: Starting UART Boot... Target: BOOTUBL BOOTUBL commmand received. Returning CMD and command... CMD value sent. Waiting for DONE... Target: DONE DONE received. Command was accepted. Sending the UBL image Waiting for SENDIMG sequence... Target: SENDIMG SENDIMG received. Returning ACK and header for image data... ACK command sent. Waiting for BEGIN command... Target: BEGIN BEGIN commmand received. Image data sent... Waiting for DONE... Target: DONE DONE received. All bytes of image data received... Target: Writing UBL to NAND flash Target: Unprotecting blocks 0x00000001 through 0x00000018. Target: Number of blocks needed for header and data: 0x0x00000001 Target: Attempting to start in block number 0x0x00000001. Target: Erasing block 0x00000001 through 0x00000001. Target: Writing header and image data to Block 0x00000001, Page 0x00000000 [...] - above 2 messages will show for a sequence ob blocks Target: Erasing block 0x00000018 through 0x00000018. Target: Writing header and image data to Block 0x00000018, Page 0x00000000 Target: Protecting the entire NAND flash. Target: DONE Sending the Application image Waiting for SENDIMG sequence... Target: SENDIMG SENDIMG received. Returning ACK and header for image data... ACK command sent. Waiting for BEGIN command... Target: BEGIN BEGIN commmand received. Image data sent... Waiting for DONE... Target: DONE DONE received. All bytes of image data received... Target: Writing APP to NAND flash Target: Unprotecting blocks 0x00000019 through 0x00000032. Target: Number of blocks needed for header and data: 0x0x00000003 Target: Attempting to start in block number 0x0x00000019. Target: Erasing block 0x00000019 through 0x0000001B. Target: Writing header and image data to Block 0x00000019, Page 0x00000000 [...] - above 2 messages will show for a sequence ob blocks Target: Erasing block 0x0000002E through 0x00000030. Target: Writing header and image data to Block 0x0000002E, Page 0x00000000 Target: Protecting the entire NAND flash. Target: DONE Target: DONE Operation completed successfully.
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:
- for GL300a board (WM323_INTERFACE_V2 or P00928.??) and HDMI board, the module is m1300,
- for GL658 SDI board, the module is m1301,
- for WM320 Gimbal top board, the module is m0800,
- for Inspire X5 Camera Live View Encoder board, the module is also m0800,
- for FC200 Live View Encoder board the images are not part of updates; you can get them directly here.
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.
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.
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:
U-Boot Product Vesion : DJI-DEC-Uboot-1.0-rc0(2015-11-02) U-Boot 2010.12-rc2-svn3214-Dji (Nov 02 2015 - 19:39:56) Cores: ARM 486 MHz DDR: 360 MHz I2C: ready DRAM: 128 MiB NAND: 128 MiB Bad block table found at page 65472, version 0x01 Bad block table found at page 65408, version 0x01 *** Warning - bad CRC, using default environment . Net: Ethernet PHY: GENERIC @ 0xff DaVinci-EMAC Press ESC to abort autoboot in 1 seconds . Loading from nand0, offset 0x4a0000 ** Unknown image type Wrong Image Format for bootm command ERROR: can't get kernel image! . Loading from nand0, offset 0x900000 Image Name: Linux-2.6.32.17-davinci1 Created: 2015-02-12 3:09:59 UTC Image Type: ARM Linux Kernel Image (uncompressed) Data Size: 3665856 Bytes = 3.5 MiB Load Address: 80008000 Entry Point: 80008000 ## Booting kernel from Legacy Image at 80700000 ... Image Name: Linux-2.6.32.17-davinci1 Created: 2015-02-12 3:09:59 UTC Image Type: ARM Linux Kernel Image (uncompressed) Data Size: 3665856 Bytes = 3.5 MiB Load Address: 80008000 Entry Point: 80008000 Loading Kernel Image ... OK OK . Starting kernel ... . [ 0.000000] Kernel Product Vesion : DJI-GRC-Kernel-1.0-rc8(2014-11-21) [ 0.000000] Linux version 2.6.32.17-davinci1 (u@dji) (gcc version 4.3.3 (Sourcery G++ Lite 2009q1-203) ) #1 PREEMPT Thu Feb 12 11:09:57 HKT 2015 [ 0.000000] CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=00053177 ...
If both primary and recovery kernel is corrupted, the booting will end at U-Boot command line:
Loading from nand0, offset 0x4a0000 ** Unknown image type Wrong Image Format for bootm command ERROR: can't get kernel image! Loading from nand0, offset 0x900000 ** Unknown image type Wrong Image Format for bootm command ERROR: can't get kernel image! Dji-Pro #
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
.
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:
- for Ph3 Pro Gimbal Top board, you need to extract
P3X_FW_V??.??.????.bin
and then module m0800 from inside. - for GL300a board and HDMI board, extract
C1_FW_v??.??.????.bin
and then module m130? from inside. - for WM301 Live View Encoder board, firmware update only modifies Ambarella programming, but you can get the image directly here.
- for FC200 Live View Encoder board the image is also not part of updates; you can get it directly here.
- for other boards, you're on your own
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:
- for GL300a board and HDMI board, you can get it here,
- for WM320 Gimbal top board, it is here,
- for Inspire X5 Camera Live View Encoder board, it is here,
- for other boards, you're on your own.
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.
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:
Press ESC to abort autoboot in 1 seconds Dji-Pro # Unknown command '' - try 'help' Dji-Pro #
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:
Dji-Pro # mw.b 0x80008000 0xFF 0x460000
Next we need to put our kernel image into that location. There are two ways:
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:
Dji-Pro # loady 0x80008000 115200 ## Ready for binary (ymodem) download to 0x80008000 at 115200 bps...
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:
xyzModem - CRC mode, 1(SOH)/3971(STX)/0(CAN) packets, 4 retries ## Total Size = 0x003e09c0 = 4065728 Bytes Dji-Pro #
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:
- for Gimbal top board, use two pins (pin1 and pin2) of the connector which goes to OFDM for USB
D+
andD-
. The power pin of your female USB connector should go to 5V supply, and ground pin to a ground associated to the 5V supply you used. Pin map using standard USB wire colors:
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.
- for other boards, find the proper place where DM36x USB output is
Copy the kernel image on your USB stick, and put it into USB slot of your board. Then, execute the following:
Dji-Pro # usb start Dji-Pro # usb storage
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:
Dji-Pro # fatload usb 0 0x80008000 uImage
On success, you should see something like:
reading uImage . 4065728 bytes read Dji-Pro #
Be careful, you are now going to make changes to your NAND memory. Do not lose or add any zeros in the offsets.
To write Primary Kernel, execute the following commands:
Dji-Pro # nand erase 0x04a0000 0x460000 Dji-Pro # nand write 0x80008000 0x04a0000 0x460000
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:
Dji-Pro # nand erase 0x0680000 0x300000 Dji-Pro # nand write 0x80008000 0x0680000 0x300000
In case you are writing Recovery Kernel, run the commands below instead:
Dji-Pro # nand erase 0x0900000 0x460000 Dji-Pro # nand write 0x80008000 0x0900000 0x460000
Or instead, to write Recovery Kernel on the FC200 camera:
Dji-Pro # nand erase 0x0980000 0x300000 Dji-Pro # nand write 0x80008000 0x0980000 0x300000
You can write the same kernel image over the two locations. But if the recovery kernel works, there is no reason to overwrite it.
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:
encrypt device:at88 found
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:
- for GL300a board and HDMI board, you can get it here.
- for WM320 Gimbal top board, it is here.
- for other boards, you're on your own - but one of the images above will probably work
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! Products of P2 series 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:
mw.b 0x80008000 0xFF 0xa0000 usb start usb storage fatload usb 0 0x80008000 dm365_secret.bin nand erase 0x0d60000 0xa0000 nand write 0x80008000 0x0d60000 0xa0000
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, 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.
You will also need a valid UbiFS Root Filesystem image. It is not a part of firmware update, so you need to find one:
- for GL300a board and HDMI board, you can get it here.
- for WM320 Gimbal top board, it is here,
- for Inspire X5 Camera Live View Encoder board, here is a version which was never updated (factory FW), and here is one that got some updates,
- for WM301 Live View Encoder board, it is here,
- for FC200 Live View Encoder board, it is here,
- for other boards, you're on your own.
Since we have no unused space on the disk to fit our partition, we will have to temporarily sacrifice our primary kernel. To overwrite the primary kernel with our Recovery Root Filesystem, insert USB stick with the partition image, boot to u-boot Console and execute:
mw.b 0x82000000 0xFF 0x400000 usb start usb storage fatload usb 0 0x82000000 dm365_recovery_rootfs.bin nand erase 0x04a0000 0x400000 nand write 0x82000000 0x04a0000 0x400000
For FC200 camera from P2V with different memory map, the last two commands needs to be changed, and will overwrite both kernels:
nand erase 0x0680000 0x400000 nand write 0x82000000 0x0680000 0x400000
If you are fixing FC200 board, you need to write a third kernel somewhere further, I'd suggest at 0x0a80000.
If you don't understand the above commands, or want to use serial instead of USB, read flashing kernel section.
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 will set the kernel parameters so that they point to original Root Filesystem. To change the Root Filesystem location in kernel parameters and start the kernel, boot to u-boot Console and execute:
env set bootargs 'console=ttyS0,115200n8 rw dm365_imp.oper_mode=0 video=davincifb:vid0=0,10K:vid1=0,10K:osd0=1920x1080X16,8100K mem=96MB davinci_enc_mngr.ch0_output=COMPOSITE loglevel=8 davinci_enc_mngr.ch0_mode=pal root=/dev/mtdblock1 rootfstype=cramfs ip=off lpj=1077248' nboot 80700000 0 900000 bootm 80700000
For FC200 camera from P2V, you need to mind the memory map and instead boot to your third kernel:
env set bootargs 'console=ttyS0,115200n8 rw dm365_imp.oper_mode=0 video=davincifb:vid0=OFF:vid1=OFF:osd0=480x272x16,4050K mem=96MB davinci_enc_mngr.ch0_output=LCD davinci_enc_mngr.ch0_mode=480x272 loglevel=8 root=/dev/mtdblock2 rootfstype=cramfs ip=192.168.1.10:192.168.1.5:192.168.2.2:255.255.255.0::eth0:off' nboot 80700000 0 a80000 bootm 80700000
When the Linux is started, 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:
cd /tmp; mkdir sdcard mount /dev/sda sdcard ubiformat /dev/mtd2 --sub-page-size=512 --vid-hdr-offset=2048 -f sdcard/dm365_root_ubifs.ubi
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:
ubiattach -m 2 --vid-hdr-offset=2048
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.
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 (Ambarella App), m0800 (DaVinci Processor) and 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.
This page is created by drone enthusiasts for drone enthusiasts.
If you see a mistake, or you know more about specific subject, or you see an area for improvement for the wiki - create an issue in this project and attach your patch (or describe the change you propose).