firmware update

Bjørn Mork bjorn at mork.no
Mon Dec 14 11:37:19 PST 2015


Dan Williams <dcbw at redhat.com> writes:

> See also gobi-api/GobiAPI_1.0.40/Core/QDLBuffers.[cpp|h], gobi
> -api/GobiAPI_1.0.40/Core/QDLEnum.h, and gobi
> -api/GobiAPI_1.0.40/Core/QDLProtocolServer.cpp in libqmi repo. 
>  Qualcomm released most of this in the GobiAPI drops.  Not sure what
> Sierra modified, but it looks mostly the same.

Ah, thanks.  I should look at the closest sources first I guess :)


>>    I have yet to find any docs of this switching request, but
>> snooping
>>    shows that it is this simple HDLC frame:
>> 
>>      7e 70 00 00 14 46 7e
>>     
>>    The "00 00" is a command parameter.  I have no idea of the exact
>>    meaning.  I've only observed a 0 so far.
>
> That part is odd, haven't found anything interesting about it.  The
> QCDM 0x70 command is DIAG_CMD_RAM_RW (but references calibration RAM)
> so that's probably not anything related.

Well, I don't actually know what the protocol is at this point since
this is the first and last request using that protocol.  But I see that
there is a reply which I falied to mention:

 0040  7e 02 6a d3 7e                                    ~.j.~

I don't think this is the DIAG protocol.  I believe it is the other
protocol refererred to as "DMSS Download Protocol". The reply matches a
DLOAD_ACK in that protocol.  I imagine Qualcomm has a Pentagon-sized
building full om employees doing nothing but inventing new serial
protocols :)

So far I've seen the "QDL function" of the MC7455 speak all these, as
well as the "Sahara" protocol. I'm sure that's a lof of fun if you have
the full docs for all the protocols.


>> d) SDP is what the gobi-loader [4] speaks.  It starts with a
>>   semi-doumented hello request (0x01) and ack (0x02):
>> 
>> 0040  7e 01 51 43 4f 4d 20 68 69 67 68 20 73 70 65 65   ~.QCOM high
>> spee
>> 0050  64 20 70 72 6f 74 6f 63 6f 6c 20 68 73 74 00 00   d protocol
>> hst..
>> 0060  00 00 06 06 30 00 00 00 de d3 7e                 
>>  ....0.....~
>> 
>> 0040  7e 02 51 43 4f 4d 20 68 69 67 68 20 73 70 65 65   ~.QCOM high
>> spee
>> 0050  64 20 70 72 6f 74 6f 63 6f 6c 20 74 67 74 30 00   d protocol
>> tgt0.
>> 0060  00 00 06 06 00 00 00 00 00 00 00 00 00 00 00 00  
>>  ................
>> 0070  00 30 d9 bc 7e                                    .0..~
>
> See sQDLHello::BuildHelloReq():
>
> struct sQDLRawHelloReq {
>       BYTE mCommandCode;     (eQDL_CMD_HELLO_REQ = 0x01)
>       BYTE mMagicNumber[32]; (QCOM high speed protocol)
>       BYTE mMaxVersion;      (QDL_MIN_VERSION = 0x06)
>       BYTE mMinVersion;      (QDL_MAX_VERSION = 0x06)
>       BYTE mFeatures;        (QDL_FEATURE_GENERIC_UNFRAMED/0x10 | QDL_FEATURE_QDL_UNFRAMED/0x20 = 0x30)
> };


Yes, that's what the gobi-loader has too.  But my dump doesn't match
exactly.   There are 3 extra 0 bytes after the expected 0x30 feature
field. A wider 32bit feature field in version 6 maybe?



> struct sQDLRawHelloRsp {
>       BYTE mCommandCode;     (eQDL_CMD_HELLO_RSP = 0x02)
>       BYTE mMagicNumber[24]; (same magic)
>       DWORD mReserved1;      (0x20 0x74 0x67 0x74)
>       WORD mBootMajorVersion;(0x30 0x00)
>       WORD mBootMinorVersion;
>       BYTE mMaxVersion;      (QDL_MIN_VERSION = 0x06)
>       BYTE mMinVersion;      (QDL_MIN_VERSION = 0x06)
>       DWORD mReserved2;
>       DWORD mReserved3;
>       BYTE mReserved4;
>       WfORD mReserved5;
>       WORD mReserved6;
>       BYTE mFeatures;        (QDL_FEATURE_GENERIC_UNFRAMED/0x10 | QDL_FEATURE_QDL_UNFRAMED/0x20 = 0x30)
> };

But that does sort of match, except that it looks like it has a 32 byte
magic as well instead of the mReserved1 + mBoot*Version fields.



>> e) Then the Sierra Wireless downloader starts with a part of the
>>   protocol I've found no docs for, but is implemented by the
>>   gobi-loader.  This is a start download (0x25) + ack (0x26), 
>> followed
>
> See gobi-api/GobiAPI-1.0.40/Core/QDLEnum.h and gobi
> -api/GobiAPI_1.0.40/Core/QDLBuffers.cpp:
>
> 0x25 = eQDL_CMD_OPEN_UNFRAMED_REQ
> 0x26 = eQDL_CMD_OPEN_UNFRAMED_RSP
>
>>   by data (0x27) and ack (0x28)
>
> 0x27 = eQDL_CMD_WRITE_UNFRAMED_REQ
> 0x28 = eQDL_CMD_WRITE_UNFRAMED_RSP
>
>>   The most difficult part here, is probably getting the 0x25 request
>>   right. This will tell the firware what kind of file we are sending,
>>   and the size it should expect to receive.  If you look at the
>>   gobi-loader, you'll see that it sends several files.
>
> gobi-api/GobiAPI_1.0.40/GobiQDLService/Main.cpp::Run() shows some of
> this.

Great.  I always have a hard time reading anything with a cpp extension,
but I guess I can figure it out :)

>>   There is lots of interesting info in the above, but this part seems
>>   important to understand the reply: 80 1c 38 4f 02 01 8c 36 4f 02
>
> struct sQDLRawOpenUnframedReq {
>       BYTE mCommandCode;        (0x25)
>       BYTE mImageType;          (0x80)  (used as eQDL_IMAGE_*)
>       DWORD mImageLength;       (0x024f381c)
>       BYTE mWindowSize;         (0x01, yes really 1)
>       DWORD mUnframedChunkSize; (0x024f368c)
>       WORD mReserved1;          (0x0000)
> };
>
> Oddly GobiAPI sets the chunk size to QDL_MAX_CHUNK_SIZE = 1024 * 1024 *
> 64, so not sure where this one's coming from.

It's the remaining part of the file after the 400 bytes in this request
are transferred.  I guess anything larger than the file size might do
here?

>>   And notice the same sequence in the reply ack, preceded by an
>> unknown
>>   16bit zero parameter:
>> 
>> 0040  7e 26 00 00 01 8c 36 4f 02 e7 2f 7e               ~&....6O../~
>
> Your unknown is mStatus.
>
> struct sQDLRawOpenUnframedRsp {
>       BYTE mCommandCode;
>       WORD mStatus;
>       BYTE mWindowSize;
>       DWORD mUnframedChunkSize;
> };

Ah, that makes sense.

>>   There are two notable differences in the above 0x25 request
>> compared
>>   to the ones generated by gobi-loader
>>     1) the above is much longer
>>     2) the above has slightly different "size" numbers
>> 
>>   The difference is 0x024f381c - 0x024f368c = 0x190 (400d), which is
>>   exactly the number of "extra" data bytes in the 0x25 request. 
>>  Those
>>   400 bytes is the beginning of the firmware image:
>
> Odd; GobiAPI doesn't show any firmware data being attached to the
>  eQDL_CMD_OPEN_UNFRAMED_REQ, it sends the REQ, parses the RSP, then
> starts sending data with eQDL_CMD_WRITE_UNFRAMED_REQ.  I wonder if this
> is Sierra-specific or it it's a Qualcomm enhancement since the GobiAPI
> drops stopped in 2013.

Difficult to know.  It would not be surprising if this is Qualcomm
generic, but I've never seen it used on any non Sierra device.

I note that this part of the image describes what follows.  I believe
the same upload procedure supports CWE, NVU and SPK (CWE+NVU) images.
Whatever receives it in the other end will probably use this header for
deciding what to do with the image.

>> g) The procedure is terminated with a 0x29 request and 0x2a ack:
>> 
>> 0040  7e 29 bb 4c 7e                                    ~).L~
>> 0040  7e 2a 00 00 00 00 4e e3 7e                        ~*....N.~
>
> eQDL_CMD_SESSION_DONE_REQ and eQDL_CMD_SESSION_DONE_RSP
>
>> 
>> h) Then we send a 0x2d request, which is not part of the
>>   gobi-loader. This request causes an immediate reboot into
>> application
>>   mode:
>> 
>> 0040  7e 2d 9f 0a 7e                                    ~-..~
>
> eQDL_CMD_SESSION_CLOSE_REQ

Good.  That looks like matching descriptions of those requests.



Bjørn


More information about the libqmi-devel mailing list