7.2.4 Hash Value Calculations
A hash value is a small fixed-size value that is calculated from and used to represent all the values in an arbitrary-sized block of data. If that data block is copied, a hash recalculated from the new block can be compared to the original hash. Agreement between the two hashes provides a high level of certainty that the copy is valid. There are many hash algorithms. More complex algorithms provide a more robust verification but can sometimes be too computationally demanding when used in an embedded environment, particularly for smaller devices.
Hexmate implements several hash algorithms, such as checksums and cyclic redundancy checks, which can be selected to calculate a hash value of a program image that is contained in a HEX file. This value can be embedded into that same HEX file and burned into the target device along with the program image. At runtime, the target device can run a similar hash algorithm over the program image, now stored in its memory. If the stored and calculated hashes are the same, the embedded program can assume that it has a valid program image to execute.
Hexmate's -ck
option requests that a hash be calculated, as described in
7.2.3.12 Ck Hexmate Option.
Some consideration is required when a hash value is being calculated over
memory that contains unused memory locations. Consider using Hexmate's
-fill
option (see 7.2.3.13 Fill Option) to have these locations programmed
with a known value. Avoid filling the locations where the hash value will be stored, as
memory is filled before the hash is calculated and this can result in an error.
Hexmate can produce a hash value from any Intel HEX file, regardless of which compiler produced the file and which device that file is intended to program. However, the architecture of the target device may restrict which memory locations can be read at runtime, thus requiring modification to the way in which Hexmate should perform hash calculations, so that the two hashes are calculated similarly and agree. In addition, some compilers might insert padding or phantom bytes into the HEX file that are not present in the device memory. These bytes might need to be ignored by Hexmate when it calculates a hash value and the following discussion indicates possible solutions.
Not all devices can read the entire width of their program memory. For example, Baseline
and Mid-range PIC devices can only read the lower byte of each program memory location. The
HEX file, however, will contain two bytes for each program memory word and both these bytes
will normally be processed by Hexmate when calculating a hash value. Use the
s2
suboption to Hexmate's -ck
option to have the MSB
of each 2-byte word skipped. Note, however, that this sort of
verification process will not detect corruption in the MSB of each program word.
Some devices have hardware CRC modules which can calculate a CRC hash value. If desired,
program memory data can be streamed to this module using the Scanner module to automate the
calculation. As the Scanner module reads the MSB of each program memory word first, you
need to have Hexmate also process HEX file bytes within an instruction word in the reverse
order. Use the r2
suboption to Hexmate's -ck
option to
have Hexmate process the bytes in a 2-byte word in reverse order.
Some consideration must also be given to how the Hexmate hash value encoded in the HEX file can be read at runtime.
Baseline and Mid-range PIC devices must store data in program memory using
retlw
instructions. Thus they need one instruction to store each byte
of the hash value calculated by Hexmate. Use the t34
suboption to
Hexmate's -ck
option to have Hexmate store each byte of the hash value in
a retlw
instruction. The retlw
instruction is encoded as
0x34nn
, where nn
is the 8-bit data value to be loaded to WREG when executed.