Channels ▼

Al Williams

Dr. Dobb's Bloggers

Dead Beef and DFU

October 20, 2014

A few months ago, I wrote about a combination demo board/oscilloscope/logic analyzer called LabTool . I recently wanted to fire it up and was unable to get it to work. The problem turned out to be a bad cable, but it did make me investigate something I was only slightly aware of previously: USB bootloaders with the DFU (Device Firmware Update) standard.

The old saying is that the nice thing about standards is there are so many of them. That seems to be the case with DFU, as well. The idea is that a device with a USB connector can be started in an update mode where it will present itself as a "DFU" device. Then a host computer can transfer new firmware to the device. While in DFU mode, the device doesn't perform its usual function.

This seems like a reasonable thing, and there's a USB specification that defines the whole thing. Assuming everyone follows it.

On the Linux side, I've used dfutool and dfu-util to program devices that have a DFU mode. On Windows, Atmel has Flip. Since the operation is governed by a standard, you'd think you'd be set if you had a program that knew how to download via DFU, right? Apparently not.

Several vendors provide chips that have DFU bootloaders built in. For security reasons, you usually have to erase the flash memory before you can do anything else (which is alarming since a bad flash would ruin your day). But not all of these bootloaders are created equal. Atmel and ST use DFU. NXP, the maker of the chip inside LabTool, also uses DFU.

At least some NXP chips, though, don't implement the whole thing. I was reading a blog post where someone had to reverse engineer the protocol used on the NXP devices (using the traditional hex number 0xDEADBEEF). In particular, the NXP bootloader only recognized a small subset of commands sufficient to load a more advanced bootloader that — in theory — could handle all the DFU commands.

This actually illustrates another way you can use DFU. The usual use case is to have the user reboot the device with a jumper in place (or removed) or while holding down some keys to enter DFU mode. However, the LabTool device has no software on it outside of the bootloader. Every time it starts, it waits for the host computer to send it the firmware to execute.

Of course, one of the things you could potentially load into a device like that is a more sophisticated bootloader.

If you examine the LabTool source code, turns out it doesn't really know anything about DFU either. It calls out to a private copy of dfu-util to boot the board. It is simple to figure out when that works, because the DFU device has one USB ID and the operating device has a different ID.

The file that the program sends to dfu-util has to have a DFU header on it. From the source code:

  qint16 hashSize = (size+511)/512;

    quint8 header[16];
    header[ 0] = 0x1a & 0x3f; // AES_ACTIVE:  0x1a = AES Encryption not active
    header[ 0] |= 0x00 & 0xc0; // HASH_ACTIVE: 0x00 = CMAC Hash is used, value is in HASH_VALUE
    header[ 1] = 0x3f & 0x3f; // RESERVED
    header[ 1] |= 0x00 & 0xc0; // AES_CONTROL: 0x00 = not used here
    header[ 2] = ((hashSize & 0x00ff) >>  0); // HASH_SIZE lsb
    header[ 3] = ((hashSize & 0xff00) >>  8); // HASH_SIZE msb
    header[ 4] = 0x00; //HASH_VALUE
    header[ 5] = 0x00; //HASH_VALUE
    header[ 6] = 0x00; //HASH_VALUE
    header[ 7] = 0x00; //HASH_VALUE
    header[ 8] = 0x00; //HASH_VALUE
    header[ 9] = 0x00; //HASH_VALUE
    header[10] = 0x00; //HASH_VALUE
    header[11] = 0x00; //HASH_VALUE
    header[12] = 0xff; //RESERVED
    header[13] = 0xff; //RESERVED
    header[14] = 0xff; //RESERVED
    header[15] = 0xff; //RESERVED

As more things migrate to USB connections, I expect this sort of thing will become even more common. On the other hand, I might be tempted to build a similar function into my own software so I could to things like fail safe upgrades Still, the fact that DFU is built into many different CPUs means it is here for awhile.

Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.