FirmGod

Intel HEX Parser

Paste an Intel HEX file to check every record checksum, resolve extended addresses, and see the memory regions, gaps and overlaps it actually programs.

Paste the file contents. Nothing is uploaded — parsing happens in this page.

Examples
Records60 with problems
Data bytes36 B36 bytes
Address range0x08000000to 0x08001003
Entry point0x08000195

Memory regions

Contiguous stretches the file actually programs, after every extended address record is applied.

StartEndSizeBytes
0x080000000x0800001F32 B32
0x080010000x080010034 B4

1 gap between regions. A programmer leaves these untouched, so they keep whatever was there before — usually erased flash.

  • 0x08000020 – 0x08000FFF (3.97 KiB)

Records

LineTypeAddressLenChecksumNotes
104Extended linear address0x00002F2
200Data0x080000001673
300Data0x080000101690
400Data0x080010004F0
505Start linear address0x0000459
601End of file0x00000FF

Record types in this file

00Data3
01End of file1
04Extended linear address1
05Start linear address1

The shape of a record

An Intel HEX file is a list of records, one per line, in a format that has barely changed since the 1970s:

:LLAAAATT[DD…]CC

FieldSizeMeaning
:1 charStart of record
LL1 byteNumber of data bytes that follow
AAAA2 bytesAddress, big endian
TT1 byteRecord type
DD…LL bytesThe data itself
CC1 byteChecksum

The checksum is the two's complement of the sum of every preceding byte, which means a correct record sums to zero modulo 256 including the checksum. That property makes verification trivial and is why a single flipped bit anywhere in a line is always caught.

How 16 bits address 32-bit flash

The address field is two bytes, so a data record can only reach 64 KiB on its own. Extended address records close the gap by setting a base that later data records are placed on top of:

  • Type 04, extended linear address. Its two data bytes become the upper sixteen bits of a 32-bit address. A record of 0800 sets the base to 0x08000000, which is where STM32 flash lives — hence the pattern at the top of almost every STM32 hex file.
  • Type 02, extended segment address. The older scheme, from 8086 segmentation. Its value is multiplied by sixteen rather than by 65536, so it reaches 1 MiB rather than 4 GiB.

A base stays in effect until another extended record replaces it, which is why a file that reaches across a 64 KiB boundary repeats the record. Reading the address field without applying the active base is the most common way to misread one of these files, and it is exactly the mistake that makes a bootloader appear to sit at address zero.

What the region view is for

The individual records rarely matter. What matters is which addresses the file actually programs, and that is only visible once every record is resolved and the contiguous stretches are merged.

Two things worth checking every time. Gaps are addresses the file does not touch, which a programmer leaves holding whatever was there — fine when intended, and a sign of a missing image when not.Overlaps are addresses written twice, which almost always means two builds have been concatenated by accident; the surviving value then depends on the programmer rather than on anything in the file.

Reading a failure

A programmer that rejects a file usually says very little about why. The failures are few and each has a distinct signature:

  • Bad checksum. One line was edited by hand or corrupted in transfer. The tool above shows both the stored and the expected value, and the difference often identifies which byte changed.
  • Byte count disagrees with the data. A line was truncated, usually by a mail client or a copy that clipped at a column boundary.
  • No end-of-file record. The file was cut short. Anything after the last valid record is missing, and a programmer may still write the part it did receive.
  • Records after the end-of-file record. Two files concatenated. The second image is almost certainly being ignored.

Related formats

Motorola S-record encodes the same information with a different record layout and a checksum that is a one's complement rather than a two's complement. ELF carries far more — symbols, sections, debug information — and is what a linker produces before objcopy reduces it to one of these flat formats.

To check an image against a published checksum once you have extracted it, theCRC calculator covers the standard polynomials, and thehex converter handles individual values pulled out of a record.

Frequently asked questions

How is the checksum calculated?

Add every byte of the record except the checksum itself — the byte count, both address bytes, the type, and the data — then take the two’s complement of the low byte. Equivalently, the correct checksum is whatever makes the whole record sum to zero modulo 256, which is why verifying is easier than generating.

Why does the address field only go up to 0xFFFF?

The format was designed for 8-bit machines with 16-bit address buses. Reaching beyond 64 KiB needs an extended address record that sets a base for the data records that follow: type 04 supplies the upper sixteen bits of a 32-bit address, and the older type 02 supplies a segment that is multiplied by sixteen.

What do the record types mean?

Type 00 carries data. Type 01 marks the end of the file and must be last. Types 02 and 04 set the address base for subsequent data. Types 03 and 05 record an entry point for the program, which a debugger may use and a plain programmer ignores.

My file has gaps. Is that a problem?

Not in itself. A gap simply means the file does not program those addresses, so a programmer leaves them holding whatever was there before — usually erased flash reading as 0xFF. It becomes a problem only when you expected the file to cover that space, for example when a bootloader and application were meant to be merged and one is missing.

What does an overlap mean?

Two records write the same address, which almost always means two images were concatenated by mistake. Which value ends up in flash depends on the programmer: most apply records in order so the later one wins, but nothing in the format requires that, so the result is not portable.

Can I convert this to a binary file?

Yes, but a binary has no addresses, so the conversion needs a base to subtract and a fill byte for the gaps. Tools such as objcopy take both as arguments. Converting a file with widely separated regions without specifying a fill produces a binary far larger than the data it holds.