DFU safety and booting wrong image Topic is solved

Sub forums for various specialist XMOS applications. e.g. USB audio, motor control and robotics.
User avatar
Caleb
Experienced Member
Posts: 82
Joined: Thu Apr 04, 2013 10:14 pm

DFU safety and booting wrong image

Post by Caleb »

Hi,
We currently have two XMOS-based products that feature firmware upgrade capability via DFU. The first uses an L2 device and the second a U8.
We just had a customer use DFU to put the L2 firmware on the U8 device. Obviously this is a major user failure - the firmware he installed was for a different product, filenames and everything else clearly indicate that it's for a different product..
Normally, when there's a faulty upgrade image, the bootloader reverts to the factory image (due to CRC failure). This would permit the user to retry the DFU - and use the correct firmware.
In this case, though, it appears that the U8 device boots the L2 firmware because it does not revert to the factory image. I've recreated this scenario. It seems that the U8 must be running the L2 programs, attempting to initialize the non-existing external USB PHY, etc and so it's unable to communicate.

First, is there any way to force the device to revert to the factory image if it is indeed successfully booting the L2 upgrade image? I suspect not - since USB communication is not functioning.

Is there no protection in the bootloader to prevent a U8 device from booting and running a L2 upgrade image?

How would one prevent a device from booting any unknown wrong upgrade image without making a custom bootloader that first detects such problems before booting an upgrade image? Can that be done and is there documentation on customizing the bootloader?

This will be a costly service problem because the customer made the same mistake on two devices and he's in China.

thanks, Caleb


View Solution
User avatar
Ross
XCore Expert
Posts: 966
Joined: Thu Dec 10, 2009 9:20 pm
Location: Bristol, UK

Post by Ross »

Hmm this sounds like a bad situation. Under the hood essentially the U-series is an L-series with an extra "USB tile" so will try to boot. I don't have an easy answer to this one I'm afraid.

I guess you have realised this now, but you should be using different PID's for different products then this shouldn't be possible (assuming XMOS driver being used)
User avatar
Caleb
Experienced Member
Posts: 82
Joined: Thu Apr 04, 2013 10:14 pm

Post by Caleb »

Hi Ross, I don't follow. Obviously using different PIDs - meaning each product model has a unique PID. The problem here is that the driver, which is customized to work only with one of our products ("m920"), will permit the user to DFU an image for a different product ("m905"). The DFU app does not scan the DFU image to compare PIDs. Also the bootloader does not have any awareness of PID.

Stating "Under the hood essentially the U-series is an L-series" - so far supports my theory on what's happening. When the L2 device boots, it loads the first tile and then then the second tile via xconnect link. The bootloader has to know how many tiles it's booting. Isn't there some handshaking between the first and second or Nth tile when booting? What happens when the U8 loads itself with a L2 image's tile 0 program and then starts to boot tile 1? Does it just hang?

Can the bootloader program be customized? If so, I'm still finding it difficult to imagine a bullet-proof method for determining whether an upgrade image is valid. Perhaps a cookie could be placed in the upgrade image and the bootloder could ignore an upgrade image that doesn't contain the correct cookie - despite whether that image is otherwise bootable.
User avatar
Ross
XCore Expert
Posts: 966
Joined: Thu Dec 10, 2009 9:20 pm
Location: Bristol, UK

Post by Ross »

Caleb wrote:Hi Ross, I don't follow. Obviously using different PIDs - meaning each product model has a unique PID. The problem here is that the driver, which is customized to work only with one of our products ("m920"), will permit the user to DFU an image for a different product ("m905"). The DFU app does not scan the DFU image to compare PIDs. Also the bootloader does not have any awareness of PID.
You are correct in your instance, sorry was thinking about some of our customers when the image is integrated into the update app. I guess you are using the standard version when the user selects/browses to the bin file.

I think the best way to combat this type of bad update it to have a hard reset button (you know the kind where you have to push it in with a pin) or some sort of button you old on boot up. The boot loader could check for this and deletes any upgrade image present and therefore the factory image is booted.
Definitely a good candidate for an App note I would say, i'll raise it.
User avatar
Ross
XCore Expert
Posts: 966
Joined: Thu Dec 10, 2009 9:20 pm
Location: Bristol, UK

Post by Ross »

Caleb wrote:
Can the bootloader program be customized?
It can, see section 4 of:

Design and manufacture systems with flash memory
User avatar
Caleb
Experienced Member
Posts: 82
Joined: Thu Apr 04, 2013 10:14 pm

Post by Caleb »

Hi Ross,
Yes - I've looked at that section before but didn't take time to digest it. I still don't think I fully understand but could probably make use of it. It seems it would be very helpful to see the default version of init(), checkCandidateImageVersion(), recordCandidateImage(), reportSelectedImate(). Where can I find the version of these functions that are compiled/linked with the loader by default?

It seems that in checkCandidateImageVersion I could perform a flash read and evaluate some location(s) in the upgrade image. Perhaps it could scan the image for VID/PID or simply check the header for a cookie - or the space just after the CRC (cookie added by editing the generated upgrade image). Then the examples from Fig 3 for recordCandidateImage(), reportSelectedImate() could be used.

Is there a defined limit to the size of the code and data in init() or these other functions? Are there other readFlash functions available to link with these for reading the program partition?

Does it seem like I'm on the right track?

At some point in the past I did some trial-and-error modifying bytes in an upgrade image but I don't recall whether it's possible to put some custom data in the header - meaning, perhaps there is an unused section of the header of the upgrade image that is not included in the CRC calculation.
Or, perhaps there's a means of adding some data to the header of the upgrade image. Any documentation of this?

It makes me a little nervous to rely on an undocumented "feature" that provides the benefit I'm looking for. Perhaps it will change in future versions of tools.

thanks, Caleb

Ross wrote:
Caleb wrote:
Can the bootloader program be customized?
It can, see section 4 of:

Design and manufacture systems with flash memory
kubao
New User
Posts: 3
Joined: Tue May 19, 2015 8:46 pm

Post by kubao »

The standard solution that we use in the bootloaders for other MCUs is to have a (effectively) one-time-programmable area where the hardware ID of the board is stored. The bootloader then refuses to start the firmware with mismatched hardware ID.

In the factory, the hardware ID area is empty, and a common bootloader image is flashed onto the chips. Then it is used to store the hardware ID and the firmware image(s).

This approach could be adopted for the XMOS bootloader as well.
User avatar
Caleb
Experienced Member
Posts: 82
Joined: Thu Apr 04, 2013 10:14 pm

Post by Caleb »

kubao wrote:The standard solution that we use in the bootloaders for other MCUs is to have a (effectively) one-time-programmable area where the hardware ID of the board is stored. The bootloader then refuses to start the firmware with mismatched hardware ID.
The challenge is how to embed a unique identifier into the upgrade image so that it may be reliably found by the custom bootloader in any future upgrade images.

Apparently the CRC calculation for upgrade images includes the header data. There is some unused space in the header but I don't know how to get anything in there. I suppose I could hand-modify the image, add data to the header and modify the CRC at the end of the image.

It is possible to simply append other data to the DFU image. The computer DFU application doesn't care nor do existing versions of the DFU enpoint code. I've exploited this characteristic for another product: I pad the end of the DFU image to 64k (U8 device) and append data that the XMOS feeds to another microcontroller for its firmware upgrade.

It would be preferable to have the tools embed an identifier in the upgrade image.
User avatar
Caleb
Experienced Member
Posts: 82
Joined: Thu Apr 04, 2013 10:14 pm

Post by Caleb »

Ross wrote:
Caleb wrote:
Can the bootloader program be customized?
It can, see section 4 of:

Design and manufacture systems with flash memory
Hi Ross,
Getting into this...I don't understand from the tools guide:

I can't seem to generate an upgrade image that includes data for the data partition so perhaps that's not possible. Does the --data option for xflash only pertain to writing the factory image?

Or is it possible to generate an upgrade image that also initializes the data partition? If so, a customized booloader could subsequently evaluate the contents of the data partition to decide if the upgrade image is valid. It seems that access to flash by the customized portion of the bootloader is limited to reading the data partition.

To be safe, it would be necessary to modify the DFU endpoint - to make it first clear the area of the data partition that would be written presumably with a unique identifier.

thanks
AudioBoy
Member++
Posts: 19
Joined: Fri Jun 13, 2014 1:35 pm

Post by AudioBoy »

As it written in the descriptions, bootloader decode the image (stored in EEPROM, using the key in OTP) to RAM and then run it.
If CRC is OK, if not - bootloader will use the previous image in EEPROM, finally - the factory (the first).

Question - this CRC is for encoded image or for decoded?
It looks, than now it is for encoded, as it stored in the EEPROM.
So, if the upgrade image was from another device, with another crypt key, and it's CRC is OK - it will be wrongly decoded (due to another key) and device will not works!
It will became a "brick" because later upgrades will be impossible, also as a revert to factory!
And it will be impossible to repair it at user side, just at the factory.
(One time I make this - I will need to unsodler the EEPROM chip, put it into another PCB, where processor's JTAG was not disabled, burn it with XTAG and then return to the 1st PCB)

If CRC will be for decoded image, image with the wrong key will not run, and previous firmware will be used.
This changes in the botloader seems to me will be the best solution.