GrabDuck

Обзор «вспомогательных» утилит из GCC toolchain. Часть 2. / Софт для электронщика / ...

:

Данная статья является продолжением этой статьи. Предлагаю без лишних слов перейти к обзору оставшихся утилит.

objcopy

На самом деле, эта утилита не является «вспомогательной». В toolchain’ах она используется для формирования файла прошивки (в виде *.hex или *.bin).

Дело в том, что линкер (ld) формирует выходной (исполняемый) файл в формате ELF. Этот формат является стандартом исполняемых файлов в большинстве UNIX-подобных систем. Кроме, собственно, кода и данных (секций .text и .data и т. д) ELF-файл содержит кучу дополнительной информации (заголовок, сведения о динамических зависимостях, отладочную информацию и т. д.). В случае МК – нам нужна «голая» прошивка, без заголовков и отладочной информации.

Рассматриваемая утилита позволяет извлечь необходимые нам секции из ELF-файла.

В самом простом случае, это делается следующей командой:

arm-none-eabi-objcopy.exe -O ihex LcdTest.elf LcdTest.hex

ключ "–O" определяет формат выходного файла. Нам, прежде всего, интересны форматы «ihex» и «binary».

На самом деле, objcopy очень мощная утилита, которая позволяет производить множество манипуляций с объектными и ELF файлами. Можно удалять, добавлять, переименовывать секции, менять точку входа и т. д.

Например, можно «вытянуть» из ELF только секцию .data в бинарный файл.

arm-none-eabi-objcopy.exe -O binary -j .data LcdTest.elf LcdTest.bin

Но все эти возможности (IMHO) необходимы уж в очень специфических случаях, поэтому не вижу смысла разбирать все возможности утилиты.

objdump

Очень полезная утилита. Позволяет получить дательную информацию по внутренностям объектного файла, в т. ч дизассемблировать код.
Запустив утилиту с ключом «-x» (x – показать содержимое всех заголовков), мы получим огромною «простыню» текста, в котором содержится информация о секциях, символах, таблицах вызовов, и т. д

arm-none-eabi-objdump.exe -x LCD.o

Результат:


Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00000000  00000000  00000000  00000034  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00000000  00000000  00000000  00000034  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  00000000  00000000  00000034  2**0
  
  ... очень много букв ...

Еще более полезной функцией данной утилиты является возможность дизассемблировать файл (ключ «–D»). Более того, если объектный файл содержит отладочную информацию – можно дополнительно указать ключ «-S», и утилита выдаст «смещанный код»: итроки исходного кода + соответствующее дизассемблированные команды.

Пример:

arm-none-eabi-objdump.exe -DS LCD.o

Результат:


Disassembly of section .text.ClrCS:

00000000 <ClrCS>:
//--------------------------------------------------------
static __inline void SetCS(void) {
        GPIO_SetBits(GPIOA , GPIO_Pin_1);
}

static __inline void ClrCS(void) {
   0:   b580            push    {r7, lr}
   2:   af00            add     r7, sp, #0
        GPIO_ResetBits(GPIOA , GPIO_Pin_1);
   4:   f44f 6000       mov.w   r0, #2048       ; 0x800
   8:   f2c4 0001       movt    r0, #16385      ; 0x4001
   c:   f04f 0102       mov.w   r1, #2
  10:   f7ff fffe       bl      0 <GPIO_ResetBits>
}
  14:   bd80            pop     {r7, pc}
  16:   bf00            nop 
ranlib
Утилита предназначена для индексирования содержимого статических библиотек (архивов, созданных утилитой ar). Утилита индексирует все символы всех объектных файлов внутри архива и помешает сам индекс в архив. Наличие такого индекса существенно уменьшает время линковки больших статических библиотек.

Пример:

arm-none-eabi-ranlib.exe liblcd.a

readelf

Утилита предназначена для получения информации по внутренностям ELF файла. Позволяет просмотреть информацию по секрециям, символам, динамическим зависимостям. В принципе, практически всю эту информацию можно получить с помощью «objdump -x».

Например, получение информации по секциям, содержащимся в ELF ( ключ «-S»):

arm-none-eabi-readelf.exe -S LcdTest.elf

Результат:


There are 18 section headers, starting at offset 0x220d0:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .isr_vector       PROGBITS        08000000 008000 0001d0 00   A  0   0  1
  [ 2] .text             PROGBITS        080001d0 0081d0 00b5cc 00  AX  0   0  8
  [ 3] .bss              NOBITS          20000000 018000 000c1c 00  WA  0   0  4
  [ 4] ._user_heap_stack NOBITS          20000c1c 018000 000080 00  WA  0   0  1
  [ 5] .ARM.attributes   ARM_ATTRIBUTES  00000000 01379c 00002f 00      0   0  1
  [ 6] .debug_info       PROGBITS        00000000 0137cb 0052f0 00      0   0  1
  [ 7] .debug_abbrev     PROGBITS        00000000 018abb 0011e7 00      0   0  1
  [ 8] .debug_loc        PROGBITS        00000000 019ca2 002392 00      0   0  1
  [ 9] .debug_aranges    PROGBITS        00000000 01c038 0006c0 00      0   0  8
  [10] .debug_ranges     PROGBITS        00000000 01c6f8 000588 00      0   0  8
  [11] .debug_line       PROGBITS        00000000 01cc80 002649 00      0   0  1
  [12] .debug_str        PROGBITS        00000000 01f2c9 0019f0 01  MS  0   0  1
  [13] .comment          PROGBITS        00000000 020cb9 000011 01  MS  0   0  1
  [14] .debug_frame      PROGBITS        00000000 020ccc 001340 00      0   0  4
  [15] .shstrtab         STRTAB          00000000 02200c 0000c3 00      0   0  1
  [16] .symtab           SYMTAB          00000000 0223a0 001220 10     17 164  4
  [17] .strtab           STRTAB          00000000 0235c0 00099d 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

run

Это симулятор, который теоретически позволяет нам запускать прошивку на ПК. Но он умеет только интерпретировать определенный набор инструкций (например, Thumb). Периферию он не эмулирует, а без периферии наш МК будет глух и нем.

Использовать симулятор, теоретически, можно в связке с отладчиком gdb. Для этого в отладчике перед загрузкой программы нужно выполнить команду «target sim». Вот только без симуляции периферии он, IMHO, бесполезен (ну, разве что какие-то математические алгоритмы отлаживать).

Работа с симулятором выглядит как-то так:

(gdb) target sim
Connected to the simulator.
(gdb) load
Loading section startup, size 0x44 vma 0x100000
Loading section prog, size 0x23a1c vma 0x100044
Loading section .data, size 0xb10 vma 0x200000
Start address 0x117a34
Transfer rate: 1190784 bits in <1 sec.
(gdb) run
Starting program: C:\Projects\Eclipse\MultiLock\locker.elf

size

Простенькая, но очень полезная утилита, которая показывает размер секций .text, .data и .bss в объектном или ELF файле. Это позволяет узнать: сколько ПЗУ и ОЗУ занимает собранная прошивка.

Пример:

arm-none-eabi-size.exe LcdTest.elf

Результат:


   text    data     bss     dec     hex filename
  47004       0    3228   50232    c438 LcdTest.elf

47004 – размер кода (ПЗУ)
0 – размер инициализированных данных (ПЗУ и ОЗУ)
3228 – размер неинициализированных данных (ОЗУ)

strings

Утилита предназначена для поиска строковых констант в объектном, ELF или бинарном файле. Строковой константой утилита считает последовательность (4 и более) печатных (printable) символов, которая заканчивается непечатным символом (unprintable). На практике, наряду с действительно строковыми константами, утилита находит в файле кучу мусора, которые по логике утилиты «похожи» на стоковые константы.

Пример:

arm-none-eabi-strings.exe LcdTest.elf

Результат:


bE8?
Hello
x<x|px
`00000000
<000000

strip

Утилита позволяет удалить из объектного или ELF файла символы определенного типа. Например, можно удалить из собранного файла всю отладочную информацию:

arm-none-eabi-strip.exe –g LcdTest.elf

В нашем случае, толку от данного инструмента мало. Утилита objcopy, которая используется для поручения файла прошивки, автоматически обрезает всю отладочную и прочую «ненужную» информацию.

P.S. Все, со «вспомогательными» инструментами разобрались — можно переходить к «основным орудиям труда». Предложения по темам для дальнейших статей приветствуются :)