Ошибка базы данных WordPress: [Table './meandr_base/anzpz_usermeta' is marked as crashed and last (automatic?) repair failed]
SELECT user_id, meta_key, meta_value FROM anzpz_usermeta WHERE user_id IN (1) ORDER BY umeta_id ASC

Формат файлов *.hex — Меандр — занимательная электроника
Site icon Меандр — занимательная электроника

Формат файлов *.hex

Многие наверняка замечали, что большинство файлов прошивок для различных контроллеров, процессоров, микросхем памяти и прочих подобных вещей хранится либо в бинарных файлах, в которых информация записана именно в том виде и в том порядке, в котором она записана в памяти железки (т.е. это тупо дамп памяти), либо в файлах с расширением hex. Вот в этой статье мы и расскажем о том, что же это за формат и зачем он вообще нужен.

Для начала разберёмся — чем же оказались неудобны бинарники? Во-первых, в таблице ASCII некоторым кодам соответствуют непечатные символы, соответственно, бинарный файл не может быть целиком просмотрен или распечатан в текстовом режиме. Во-вторых, прошивка редко занимает целиком всю память железки, а бинарник — это, как уже было сказано выше, дамп памяти целиком. И ладно, если бы вся полезная информация всегда располагалась, например, в начале файла, пустое окончание можно было бы от бинарника просто отрезать. Но нет, чаще всего информация в бинарнике расположена не одним куском, а находится в различных частях файла и между кусками с полезной информацией расположены пустые места, которые и хранить и распечатывать особого смысла нет.

Почесав репу над этими двумя недоразумениями, джедаи из Intel придумали формат hex или Intel-hex, ставший впоследствии стандартом де-факто для записи всяких разных прошивок. Мне больше нравится говорить Intel-hex, поскольку в этом случае не возникает путаницы и сразу понятно, что речь идёт об информации в файлах *.hex, а не просто о представлении данных в шестнадцатиричном виде. Ну ладно, вернёмся к проблемам Intel и к их решению.

Проблему с непечатными символами решили очень просто, — в Intel-hex формате двоичные данные, представленные в шестнадцатиричном виде, записываются символами ASCII. Например, число «00111111» в шестнадцатиричном виде равно «3F» и в формате Intel-hex будет записано двумя символами: «3» и «F».

Не на много сложнее оказалось и решение проблемы с пустыми местами. В *.hex файлы решили писать не всё подряд, а только полезные данные (т.е. пустые места бинарника решили не писать). Но в этом случае нужно было кроме самих данных ещё и как-то указывать адреса, по которым эти данные расположены. Окей, стали писать ещё и адреса.

Далее добавили ещё данные о точке входа, ну чтоб можно было записанную таким образом программку сразу и исполнять, и придумали разбивать всю информацию на специальные блоки, называемые «записями», чтоб отличить где что записано: где данные, где адреса, где точки входа. Вот, собственно, из этих записей и состоит весь *.hex файл.

Записи бывают следующих типов:

Все записи имеют следующий формат:

RECORD MARK
‘:’
RECLEN LOAD OFFSET RECTYPE INFO or DATA CHKSUM
1 byte 2 bytes 1 byte n bytes 1 byte
1 ASCII 2 ASCII 4 ASCII 2 ASCII 2*n ASCII 2 ASCII

В данном случае:

А теперь о некоторых типах записей подробнее:

Extended Linear Address Record
RECORD MARK RECLEN LOAD OFFSET RECTYPE ULBA CHKSUM
‘:’ ’02’ ‘0000’ ’04’ 2 bytes 1 byte

Эта запись используется в 32-битных прошивках для определения битов 16-31 линейного базового адреса (LBA), при этом биты 0-15 равны нулю. Сами биты 16-31 называются верхним базовым адресом (ULBA).

Абсолютное значение адреса байта данных в памяти получается добавлением LBA к смещению, вычисленному сложением поля LOAD OFFSET в последующих записях данных и индекса байта в поле DATA этих записей. Все суммирования делаются по модулю 4G, таким образом мы получаем циклический (от FFFFFFFFh происходит переход к 00000000h) 4-х гигабитный (4G=232) линейный адрес (Linear Address).

ByteAddr=(LBA+DRLO+DRI) mod 4G, где

DRLO — значение поля LOAD OFFSET в записи данных

DRI — индекс байта в поле DATA записи данных

Когда запись «Extended Linear Address» встречается в файле, — заданный с помощью неё линейный базовый адрес (LBA) действует для всех последующих записей данных, пока не встретится новая запись «Extended Linear Address». По умолчанию LBA=00000000h.

Extended Segment Address Record
RECORD MARK RECLEN LOAD OFFSET RECTYPE USBA CHKSUM
‘:’ ’02’ ‘0000’ ’02’ 2 bytes 1 byte

Эта запись используется для определения битов 4-19 базового адреса сегмента (SBA), при этом биты 0-3 равны нулю. Сами биты 4-19 называются верхним адресом сегмента (USBA).

Абсолютное значение адреса байта данных в памяти получается добавлением SBA к смещению, вычисленному сложением поля LOAD OFFSET в последующих записях данных и индекса байта в поле DATA этих записей. Сложение LOAD OFFSET и индекса выполняется по модулю 64K, таким образом мы получаем циклический (от смещения FFFFh происходит переход к 0000h) 64-х килобитный (64K=216) адрес в заданном сегменте.

ByteAddr=SBA+[(DRLO+DRI) mod 64K], где

DRLO — значение поля LOAD OFFSET в записи данных

DRI — индекс байта в поле DATA записи данных

Когда запись «Extended Segment Address» встречается в файле, — заданный с помощью неё базовый адрес сегмента (SBA) действует для всех последующих записей данных, пока не встретится новая запись «Extended Segment Address». По умолчанию базовый адрес сегмента (SBA) равен нулю.

Start Linear Address Record
RECORD MARK RECLEN LOAD OFFSET RECTYPE EIP CHKSUM
‘:’ ’04’ ‘0000’ ’05’ 4 bytes 1 byte

Эта запись используется для указания адреса, с которого начинается исполнение объектного файла. Значение поля EIP определяет адрес, который заносится в регистр EIP процессора. Отметим, что эта запись определяет только адрес точки старта кода в пределах 32-х битного линейного адресного пространства защищённого режима процессора 80386. В реальном режиме для определения точки старта должна использоваться запись Start Segment Address Record, поскольку она описывает содержимое пары регистров CS:IP, необходимое для реального режима.

Запись «Start Linear Address» может быть расположена в любом месте файла, если же такой записи нет, то загрузчик использует адрес старта по умолчанию.

Start Segment Address Record
RECORD MARK RECLEN LOAD OFFSET RECTYPE CS:IP CHKSUM
‘:’ ’04’ ‘0000’ ’03’ 4 bytes 1 byte

Эта запись используется для указания адреса, с которого начинается исполнение объектного файла. Значение поля CS:IP определяет 20-ти битный адрес, заносимый в регистры CS:IP процессора. Отметим, что эта запись определяет только адрес входа в 20-ти битном сегментированном адресном пространстве процессоров 8086/80186.

Запись «Start Segment Address» может быть расположена в любом месте файла, если же такой записи нет, то загрузчик использует адрес старта по умолчанию.

Источник: http://radiohlam.ru/

Exit mobile version