[Hardware Hacking General] E:V:A:
Qualcomm/Intel HEX files

This is a text-based (ASCII) file format originally introduced by Intel to

distribute PROM code, that include error checking for redundancy. Today

Qualcomm use this file format to distribute their modem/processor boot code

used in downloading bootloaders in the OEM build-processes or for emergency

download modes etc. There are several dozens of variations on the HEX format,

so we will not go into the details of other formats or uses, but only for that

used in the Qualcomm bootchain.

To convert the Qualcomm provided Intel-HEX files into binaries, you can either

use the simple pre-compiled windows and linux binary hex2bin (src), or you can

compile the much more flexible and complete EPROM file-converter utilities of

srecord, which can handle many more HEX formats including hex-diffing and

hex-merging etc. One of the Qualcomm image build "toolkit" programs, the

"emmcswdownload.exe" already contain a hex-to-bin converter, but it is usually

appending more than one binary file as described in the required XML partition

file. For details about this see the next section about QFIT.

Next we jump right into describing the Qualcomm (aka Intel-32) HEX-file

format. The content of a typical HEX-file, let's say the MPRG8660.HEX are as

follows:

:020000042A00D0
:10000000D1DC4B843410D773FFFFFFFFFFFFFFFFEE
:10001000FFFFFFFF500000005000002A348802005C
:10002000348802008488022A000000008488022AA2
...
:108850001CAF012A000000005CC4012A8CC4012A5C
:1088600000000000FCBF012AFCC0012A04C0012A4C
:10887000BCC2012AC4C2012ACCC2012A00000000E5
:0488800000000000F4
:040000052A000000CD
:00000001FF

Let's break this down. First things to know are that:

Each line is a record.

Hexadecimal values are always in uppercase.

The sum of all the bytes in each record should be 00 (modulo 256).

So for example, a typical record can be broken down as:

[SIZE=2]
:[B][COLOR=DarkRed]10[/COLOR]0020[COLOR=Blue]00[/COLOR][/B][COLOR=Green]348802008488022A000000008488022A[/COLOR][COLOR=Red][B]A2[/B][/COLOR]

: 10 0020 00 348802008488022A000000008488022A A2[/SIZE] [SIZE=2]
| | | | ----------------+--------------- |
| | | | | +-- Checksum (1 byte)
| | | | +-------------------- Data (0-255 bytes, here 16)
| | | +--------------------------------------- Record type (1 byte)
| | +------------------------------------------- Address (2 bytes)
| +----------------------------------------------- Data Byte Count (1 byte, here 16)
+-------------------------------------------------- Start of record delimiter[/SIZE]

There are 6 record types defined (for Intel-32 HEX):

'00' = Data Record

'01' = End Of File (EOF) Record

'02' = Extended Segment Address Record

'03' = Start Segment Address Record

'04' = Extended Linear Address Record

'05' = Start Linear Address Record

But only 4 are used for Qualcomm processor/modem HEX-files:

00: Data Record

01: End Of File (EOF) Record

04: Extended Linear Address Record

05: Start Linear Address Record

Where "04" (Extended Linear Address Record) allow for 32 bit addressing (up to

4GiB). The address field is 0000, the byte count is 02. The two data bytes

(two hex digit pairs in big-endian order) represent the upper 16 bits of the

32 bit address for all subsequent 00 type records until the next 04 type

record comes. If there is not a 04 type record, the upper 16 bits default to

0000. To get the absolute address for subsequent 00 type records, the address

specified by the data field of the most recent 04 record is added to the 00

record addresses.

While the "05" (Start Linear Address Record), contain the address that is

loaded directly into the program counter (PC / R15) of the ARM processor. The

address field is 0000, the byte count is 04. The 4 data bytes represent the

32-bit value loaded into the register.

NOTE: The data field endianness may be byte-swapped.

Qualcomm use the following convention for naming their HEX boot-loader

"programmer" files. This is especially true when used in conjunction with

their emmcswdownload.exe. (See this section.)

yPRGxxxx.HEX

where "y" is one of the following:

[SIZE=2]N = NAND
A = NOR
M = eMMC
arm = Is used to bypass automatic selection by QPST by renaming a custom version to "armprg.hex"
flash = ??
[/SIZE]

<< Here Be More Dragons >>