Intel hex опис формату файлу, pc, programming

У цій статті наведено переклад документа компанії Intel "Hexadecimal Object File Format Specification" - опис широко поширеного текстового формату файлу для зберігання двійкових даних (формат Intel HEX). У тексті часто зустрічається термін "Шестнадцатерічний об'єктний файл", який насправді відповідає просто якийсь прошивці мікроконтролера (наприклад, файл firmware мікроконтролера AVR. Має розширення HEX), т. Е. Мається на увазі просто сам HEX-файл.

Цей документ описує формат шістнадцятирічного об'єктного файлу для 8-, 16- і 32-бітних мікропроцесорів Intel. Шістнадцятковий формат підходить для вхідних даних программаторов PROM або апаратних емуляторів.

Примітка перекладача: оскільки формат Intel HEX давно став стандартному де-факто, він застосовується для зберігання даних і коду майже для всіх без винятку вбудованих (embedded) архітектур мікроконтролерів і процесорів, не тільки для процесорів Intel x86.

Примітка перекладача: 8-, 16- і 32-бітові формати відрізняються один від одного тільки логічною структурою, т. Е. Появою в HEX-файлі різних типів записів (типи записів див. Далі). Загальний формат HEX-файлу і кодування записів в ньому при цьому залишається незмінними.

Шістнадцяткове подання виконуваного файлу закодовано за допомогою цифробуквене символів ASCII. Наприклад, 8-бітове двійкове значення 00111111 відповідає шістнадцятиричним 3F. Щоб закодувати це значення в ASCII, застосовується 2 байта символів ASCII. Перший байт для нашого прикладу кодування буде дорівнює ASCII-символу '3' (в двійковому вигляді це 00110011 або 033H) і другий байт буде дорівнює ASCII-символу 'F' (01000110 або 046H). Для кожного значення байта порядок проходження шістнадцятирічних цифр завжди такий, що старша цифра йде першою. ASCII-представлення двійкового коду завжди вимагає в 2 рази більше байт даних, ніж двійкове подання даних.

На малюнку показаний приклад вмісту HEX-файлу.

Intel hex опис формату файлу, pc, programming

Примітка перекладача: для кожної окремої архітектури процесора можуть знадобитися далеко не всі записи. Наприклад, для мікроконтролерів AVR реально використовуються тільки типи записів Data Record і End of File Record. Лінкер GCC також додає в файл для AVR запис Start Segment Address Record (ближче до кінця файлу), але цей запис зазвичай ніяк не використовується (не враховується при прошивці мікроконтролера программатором).

[Загальний формат запису (General Record Format)]

Кожен запис в HEX-файлі (рядок) починається з поля маркера початку запису RECORD MARK. що містить ASCII-код 03AH, символ двокрапки ':'.

Наступне поле кожного запису RECLEN. яке задає кількість байт корисної інформації, яка міститься в записі (ці байти йдуть за полем RECTYP). Пам'ятайте, що один байт даних представлений двома символами ASCII. Максимальне значення для поля RECLEN є шестнадцатеричное 'FF', т. Е. Корисних даних в запису може бути від 0 до 255 байт.

Наступне поле в кожному записі RECTYP. яке позначає тип цього запису. Поле RECTYP використовується для інтерпретації інформації в запису. Ось як кодуються типи записів:

Наступне поле в кожному записі змінної довжини, поле INFO / DATA. Воно складається з нульового або більшої кількості байт (байт може бути від 0 до 255, відповідно до значення поля RECLEN), де кожен байт закодований як пара шістнадцяткових цифр. Інтерпретація цього поля залежить від значення поля RECTYP.

І нарешті, кожен запис закінчується полем CHKSUM. яке містить шестнадцатеричное ASCII уявлення контрольної суми (додаток до двох, додатковий код, two's complement sum) від усіх байт записи, починаючи включно від поля RECLEN, і закінчуючи включно останнім байтом поля INFO / DATA. При цьому контрольна сума обчислюється не від самих символів ASCII, а від подання кожної пари HEX-символів ASCII як одного байта. Таким чином, сума всіх пар в запису після конвертації кожної пари в двійкове подання, від поля RECLEN включно до поля CHKSUM включно, дорівнює 0.

[Extended Linear Address Record (тільки для 32-бітного формату)]

(LBA + DRLO + DRI) MOD 4G

Де DRLO одно полю LOAD OFFSET в запису Data Record, DRI дорівнює індексу байта в запису Data Record.

Коли запис Extended Linear Address Record задає значення LBA, воно може з'явитися в будь-якому місці 32-бітного шістнадцятирічного об'єктного файлу. Це значення залишається ефективним, поки не з'явиться інший запис Extended Linear Address Record. Значення за замовчуванням для LBA дорівнює нулю, поки не з'явиться запис Extended Linear Address Record.

Примітка перекладача: в HEX-файлах AVR запис Extended Linear Address Record не використовується.

В окремих полях записи є наступне вміст:

RECORD MARK
Це поле містить байт 03AH, символ двокрапки, закодований шістнадцятковим символом ASCII ( ':').

RECLEN
Це поле містить два байта 03032H, що кодують шестнадцатерічнимі символами ASCII '02', що означає довжину в байтах інформації даних ULBA, що містяться в цьому записі.

LOAD OFFSET
Це поле містить байти 030303030H, що кодують шестнадцатерічнимі символами ASCII "0000 ', оскільки поле не використовується в цьому записі.

RECTYP
Це поле містить байти 03034H, що кодують шестнадцатерічнимі символами ASCII '04', що задає тип запису Extended Linear Address Record.

CHKSUM
Це поле містить контрольну суму полів RECLEN, LOAD OFFSET, RECTYP і ULBA.

[Extended Segment Address Record (16- або 32-бітний формат)]

SBA + ([DRLO + DRI] MOD 64K)

Де DRLO одно полю LOAD OFFSET в Data Record, DRI дорівнює індексу байта в Data Record.

Коли запис Extended Segment Address Record задає значення SBA, воно може з'явитися в будь-якому місці 16-бітного шістнадцятирічного об'єктного файлу. Це значення залишається ефективними, поки не з'явиться інший запис Extended Segment Address Record. Значення SBA за замовчуванням дорівнює 0, поки не з'явиться запис Extended Segment Address Record.

Примітка перекладача: в HEX-файлах AVR запис Extended Segment Address Record не використовується.

В окремих полях записи є наступне вміст:

RECORD MARK
Це поле містить байт 03AH, символ двокрапки, закодований шістнадцятковим символом ASCII ( ':').

RECLEN
Це поле містить два байта 03032H, що кодують шестнадцатерічнимі символами ASCII '02', що означає довжину в байтах інформації даних USBA, що містяться в цьому записі.

LOAD OFFSET
Це поле містить байти 030303030H, що кодують шестнадцатерічнимі символами ASCII "0000 ', оскільки поле не використовується в цьому записі.

RECTYP
Це поле містить байти 03032H, що кодують шестнадцатерічнимі символами ASCII '02', що задає тип запису Extended Segment Address Record.

CHKSUM
Це поле містить контрольну суму полів RECLEN, LOAD OFFSET, RECTYP і USBA.

[Data Record (8-, 16- або 32-бітний формат)]

Примітка перекладача: цей запис - основна для HEX-файлу прошивок AVR. Зазвичай в одній такого запису (рядку) закодовано 16 байт коду програми firmware (в поле RECLEN міститься значення '10'). В останньому рядку Data Record файлу HEX може міститися менше 16 байт (в поле RECLEN з'явиться відповідне значення).

В окремих полях записи є наступне вміст:

RECORD MARK
Це поле містить байт 03AH, символ двокрапки, закодований шістнадцятковим символом ASCII ( ':').

RECLEN
Це поле містить дві шістнадцяткові цифри ASCII, які задають кількість байт даних, що знаходяться в запису. Максимальне значення становить 'FF' або 04646H (що відповідає десятковому значення 255).

RECTYP
Це поле містить байти 03030H, що кодують шестнадцатерічнимі символами ASCII '00', що задає тип запису Data Record.

DATA
Це поле містить пари шістнадцяткових цифр ASCII, де кожна пара кодує один байт даних.

CHKSUM
Це поле містить контрольну суму полів RECLEN, LOAD OFFSET, RECTYP і DATA.

[Start Linear Address Record (тільки 32-бітний формат)]

Примітка перекладача: в HEX-файлах AVR запис Start Linear Address Record не використовується.

В окремих полях записи є наступне вміст:

RECORD MARK
Це поле містить байт 03AH, символ двокрапки, закодований шістнадцятковим символом ASCII ( ':').

RECLEN
Зто поле містить 03034H, що кодують шестнадцатерічнимі символами ASCII '04', що вказує довжину, в байтах, вмісту регістра EIP в цьому записі.

LOAD OFFSET
Це поле містить 030303030H, що кодують шестнадцатерічнимі символами ASCII "0000 ', оскільки це поле не використовується в запису.

RECTYP
Це поле містить 03035H, що кодують шестнадцатерічнимі символами ASCII '05', що задає тип запису Start Linear Address Record.

CHKSUM
Це поле містить контрольну суму полів RECLEN, LOAD OFFSET, RECTYP і EIP.

[Start Segment Address Record (16- або 32-бітний формат)]

В окремих полях записи є наступне вміст:

RECORD MARK
Це поле містить байт 03AH, символ двокрапки, закодований шістнадцятковим символом ASCII ( ':').

RECLEN
Зто поле містить 03034H, що кодують шестнадцатерічнимі символами ASCII '04', що вказує довжину, в байтах, вмісту регістрів CS / IP в цьому записі.

LOAD OFFSET
Це поле містить 030303030H, що кодують шестнадцатерічнимі символами ASCII "0000 ', оскільки це поле не використовується в запису.

RECTYP
Це поле містить 03033H, що кодують шестнадцатерічнимі символами ASCII '03', що задає тип запису Start Segment Address Record.

CS / IP
Це поле містить вісім символів ASCII шістнадцятирічних цифр, що вказують вміст 16-бітного регістра CS і 16-бітного регістра IP. Старший байт вмісту регістра CS знаходиться в парі символів 10 і 11, молодший в парі символів 12 і 13. Старший байт вмісту регістра IP знаходиться в парі символів 14 і 15, молодший в парі символів 16 і 17.

CHKSUM
Це поле містить контрольну суму полів RECLEN, LOAD OFFSET, RECTYP і CS / IP.

[End of File Record (8-, 16- або 32-бітний формат)]

Запис End of File Record вказує кінець шістнадцятирічного об'єктного файлу. Це рядок, в якій містяться символи ': 00000001FF'.

Примітка перекладача: в HEX-файлах мікроконтролера AVR цей запис також використовується для позначення кінця файлу.

В окремих полях записи є наступне вміст:

RECORD MARK
Це поле містить байт 03AH, символ двокрапки, закодований шістнадцятковим символом ASCII ( ':').

RECLEN
то поле містить 03030H, що кодують шестнадцатерічнимі символами ASCII '00'. Оскільки цей запис не містить ніяких даних INFO / DATA, то довжина дорівнює нулю.

LOAD OFFSET
Це поле містить 030303030H, що кодують шестнадцатерічнимі символами ASCII "0000 ', оскільки це поле не використовується в запису.

RECTYP
Це поле містить 03031H, що кодують шестнадцатерічнимі символами ASCII '01', що задає тип запису End of File Record.

CHKSUM
Це поле містить контрольну суму полів RECLEN, LOAD OFFSET і RECTYP. Оскільки всі поля статичні (їх вміст незмінно), то контрольну суму також можна обчислити статично, і її значення 04646H, що кодують шестнадцатерічнимі символами ASCII 'FF'.

[Алгоритм підрахунку контрольної суми]

Байт контрольної суми CHKSUM для рядка HEX-файлу обчислюється так, щоб байтовая сума всіх корисних даних рядка і самої контрольної суми з відкиданням переповнень дорівнювала нулю. При цьому складаються не самі символи ASCII, а тільки дані, що вони представляють. Спрощений алгоритм підрахунку контрольної суми на псевдокоді для запису Data Record:

Щоб було зовсім зрозуміло, розберемо простий приклад. Ось типова рядок HEX-файлу прошивки мікроконтролера AVR (для наочності поля позначені різними кольорами):

10 3800 00 5CC000008FC0000073C0000071C00000 E9

Отже, контрольна сума CHKSUM у нас вийде, якщо складемо (відкидаючи перенесення) байти даних починаючи від поля RECLEN (0x10) до останнього байта поля DATA [RECLEN-1] (0x00), і потім віднімемо з нуля отриману суму (також відкидаючи перенесення) :

0xE9 = 0 - (0x10 + 0x38 + 0x00 + 0x00 + 0x5C + 0xC0 + 0x00 + 0x00 + 0x8F + 0xC0 + 0x00 + 0x00 + 0x73 + 0xC0 + 0x00 + 0x00 + 0x71 + 0xC0 + 0x00 + 0x00)

Якщо скласти всі байти починаючи від RECLEN до CHKSUM включно (відкидаючи перенесення), то отримаємо нуль: