EM7565 firmware updates

Bjørn Mork bjorn at mork.no
Thu Mar 8 14:58:24 UTC 2018


Bjørn Mork <bjorn at mork.no> writes:

> bjorn at miraculix:~/docs/hardware/sierra/em7565$ hexdump -vC out2 
> 00000000  02 00 00 00 30 00 00 00  02 00 00 00 02 00 00 00  |....0...........|
> 00000010  00 00 00 00 03 00 00 00  01 00 00 00 02 00 00 00  |................|
> 00000020  03 00 00 00 04 00 00 00  05 00 00 00 06 00 00 00  |................|
> 00000030
>
> Then there is nothing more in either direction.  Which is a bit
> suprising, because I usually see an error from the bootloader when I try
> this manually.  I guess the fact that the applications sends a hello
> reply indicates that sahara isn't entirely unexpected at this point.

I started suspecting that I might have messed up something when building
the GobiSerial driver, so I tried this again with the qcserial driver
instead (the QMI SDK appears to accept GobiNet+qcserial as valid).  This
time the application got a bit further before hanging, but at least far
enough to confirm the suspicion: It is using some so far unknown (to me
at least) sahara command.

It starts with the same strange 'UTUVUTUV UTUVUTUV UTUVUTUV' packet.
Maybe just meant to trigger a hello from the bootloader?  Anyway, the
hello exchange is in fact successful after this.  I guess I remembered
this wrong.  The mode change is successful, but none of the well known
commands seems supported.  But there are supported commands..

This is a transcript of the dialogue:

 >> 'UTUVUTUV UTUVUTUV UTUVUTUV'
 << sahara hello (mode=2)
 >> sahara hello response (mode=3)
 << sahara command ready
 >> sahara exec command 0x0000ff00 (sic!)
 << sahara exec response (9 bytes of data)
 >> sahara exec data request
 << 'confirmed' (yup, that's nine ascii bytes...)

>From here it goes crazy with xml, Receiving these files, with one xml
blob per URB. No headers or other metadata:


 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<log value="Binary build date: Sep 29 2017 @ 05:58:36"/>
</data>'


 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<log value="Supported Functions: program configure power benchmark read getstorageinfo erase nop "/>
</data>'


 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<log value="SWI supported functions: CWE"/>
</data>'


Then the application starts communicating in xml too, with lots of extra
spaces but no lf or cr (not that it matters to an xml parser, but I
transcribe it exactly as seen):

 >> '<?xml version="1.0" encoding="UTF-8" ?>            <data>            <getStorageInfo physical_partition_number="0" />            </data>'

 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<log value="[FLASH_INFO]"/>
</data>'

 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<log value=";This section provides flash info"/>
</data>'

 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<log value="FLASH_NAME=MT29F4G08ABBEA3W   "/>
</data>'

 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<log value="SECTOR_SIZE_IN_BYTES = 4096"/>
</data>'

 >> '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<configure MemoryName="eMMC" Verbose="0" AlwaysValidate="0" MaxDigestTableSizeInBytes="8192"  MaxPayloadSizeToTargetInBytes="16384" ZlpAwareHost="0" SkipStorageInit="0" TargetName="8960" />
</data>
'

 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<log value="NUM_PARTITION_SECTORS = 131072"/>
</data>'

 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<log value="num_physical_partitions = 1"/>
</data>'

 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<log value="TOTAL_SECTOR_SIZE_IN_BYTES= 4320"/>
</data>'

 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<log value="PAGES_IN_BLOCK = 64"/>
</data>'

 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<log value="CONFIGURATION SELECTION FOR THIS DEVICE: BLOCKSIZE:256KB and PAGESIZE:4KB"/>
</data>'

 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<log value="
"/>
</data>'

 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<log value="[BAD_BLOCK_LIST]"/>
</data>'

 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<log value=";This section provides bad block list"/>
</data>'

 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<log value="TOTAL_BAD_BLOCK=0"/>
</data>'

 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<response value="ACK" />
</data>'

 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<response value="NAK" MemoryName="NAND" MaxPayloadSizeFromTargetInBytes="2048" MaxPayloadSizeToTargetInBytes="8192" MaxPayloadSizeToTargetInBytesSupported="8192" TargetName="9x55" />
</data>'

 >> '<?xml version="1.0" encoding="UTF-8" ?>            <data>            <getStorageInfo physical_partition_number="0" />            </data>'

 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<log value="[FLASH_INFO]"/>
</data>'

 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<log value=";This section provides flash info"/>
</data>'

 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<log value="FLASH_NAME=MT29F4G08ABBEA3W   "/>
</data>'

 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<log value="SECTOR_SIZE_IN_BYTES = 4096"/>
</data>'

 >> '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<configure MemoryName="eMMC" Verbose="0" AlwaysValidate="0" MaxDigestTableSizeInBytes="8192"  MaxPayloadSizeToTargetInBytes="8192" ZlpAwareHost="0" SkipStorageInit="0" TargetName="8960" />
</data>
'
 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<log value="NUM_PARTITION_SECTORS = 131072"/>
</data>'

 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<log value="num_physical_partitions = 1"/>
</data>'

 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<log value="TOTAL_SECTOR_SIZE_IN_BYTES= 4320"/>
</data>'

 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<log value="PAGES_IN_BLOCK = 64"/>
</data>'

 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<log value="CONFIGURATION SELECTION FOR THIS DEVICE: BLOCKSIZE:256KB and PAGESIZE:4KB"/>
</data>'

 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<log value="
"/>
</data>'

 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<log value="[BAD_BLOCK_LIST]"/>
</data>'

 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<log value=";This section provides bad block list"/>
</data>'

 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<log value="TOTAL_BAD_BLOCK=0"/>
</data>'

 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<response value="ACK" />
</data>'

 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<response value="ACK" MemoryName="NAND" MaxPayloadSizeFromTargetInBytes="2048" MaxPayloadSizeToTargetInBytes="8192" MaxPayloadSizeToTargetInBytesSupported="8192" TargetName="9x55" />
</data>'

 >> '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="20339" filename="spkg.cwe" physical_partition_number="0" start_sector="-1" />
</data>
'

 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<log value="INSIDE HANDLE PROGRAM"/>
</data>'

 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<log value="start_sector 0, last_sector_address 20339"/>
</data>'

 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<log value="SWI program command for CWE image spkg.cwe"/>
</data>'

 << '<?xml version="1.0" encoding="UTF-8" ?>
<data>
<response value="ACK" rawmode="true" />
</data>'


>From here the host firmware update application starts sending the image
as 2048 byte raw binary sections, with no further framing or escaping
AFAICS.  But only 4 of such blobs are completed before the modem stops
responding to the URBs.  So things stop pretty quickly.  I note that
these numbers match the negotiated MaxPayloadSizeFromTargetInBytes and
MaxPayloadSizeToTargetInBytes, whatever that means.


Anyway, I guess we have enough info to start implementing this
protocol. Switching into the XML mode should be simple to do.  And the
XML part of the protocol also looks pretty simple from the above.  Most
of the data from the bootloader appears to be log messages, having
simple ascii text as value.


There are only 4 types of XML messages exchanged (so far):

 log (from bootloader)
    value is text
 response (from bootloader),
    value is ACK or NAK
    often with with more attributes being part of the current negotiation
 configure (from updater)
    with a number of attributes to be negotiated
 program (from updater)
    with a number of attribues describing both the file to be uploaded
    and destination


Now I'm not entirely sure how we're supposed to match ACKs or NAKs to
the exact "configure" or "program" request, as there aren't any any
sequence numbers or similar.  I guess the remaining attributes will
tell. Or we're only supposed to have one outstanding request at a time.

There are also two spurious ACKs with no attributes in the above message
exchange.  I don't understand the meaning of those.

The configure -> response part looks somewhat like a negotiation, but
not quite.  I don't understand why the updater repeat most of the
attributes in the second request (except MaxPayloadSizeToTargetInBytes),
including the obviously bogus TargeName.  And then I certainly don't
understand why the bootloader acks the second request...

The numbers in the program request (20339*4096=83308544) matches the
file size (83306532), so that makes sense.  The file name doesn't match
the input file name, but I guess it doesn't matter.

Well, that's as far as I got for now...



Bjørn


More information about the libqmi-devel mailing list