Откуда берутся адреса в файлах S-Record?

Я разрабатываю автономное приложение для микроконтроллера ARM Cortex-M и, исследуя структуру файла S-Record, обнаружил, что у меня есть какое-то непонимание того, как адреса представлены в формате S-Record.

У меня есть переменная, определенная в моем исходном коде так:

      uint32_t g_ip_address = IP_ADDRESS(10, 1, 0, 56); // in LE: 0x3800010A

Когда я запускаю objdump, я вижу, что переменная попадает в раздел .data по адресу 0x1ffe01c4:

      $ arm-none-eabi-objdump -t application.elf | grep g_ip_address
1ffe01c4 g     O .data  00000004 g_ip_address

Это имеет смысл, учитывая, что раздел памяти моего сценария компоновщика выглядит так, а .data отправляется в ОЗУ:

      MEMORY
{
  FLASH (rx)         : ORIGIN = 0x00000000, LENGTH = 0x0200000  /*   2M */
  RAM (rwx)          : ORIGIN = 0x1FFE0000, LENGTH = 0x00A0000  /* 640K */   
}

Однако, когда я просматриваю файл srec, я обнаруживаю, что адрес записи не 0x1FFE0000. Это 0x0005F570, который, кажется, помещает его в раздел FLASH (для ясности добавлены пробелы).

      S315 0005F570 00000000 3800010A 000010180000000014

Есть ли неявное смещение, закодированное в другой записи записи? Как objcopy получает этот новый адрес? Если это значение каким-то образом кодируется в функцию (возможно, некоторая предварительная инициализация переменных)?

В конечном итоге моя цель - иметь возможность проанализировать файл srec и исправить значение IP-адреса для создания нового файла srec. Является ли идиоматический способ сделать что-то вроде этого просто для создания структуры, которая жестко кодирует некоторую ведущую последовательность магических чисел, которую можно обнаружить в файле?

1 ответ

Решение

flash.s

      .cpu cortex-m0
.thumb

.word 0x00002000
.word reset

.thumb_func
reset:
    b reset
    
.data
.word 0x11223344

.bss
.word 0x00000000
.word 0x00000000

flash.ld

      MEMORY
{
    rom : ORIGIN = 0x08000000, LENGTH = 0x1000
    ram : ORIGIN = 0x20000000, LENGTH = 0x1000
}
SECTIONS
{
    .text   : { *(.text*)   } > rom
    .bss    : { *(.bss*)    } > ram AT > rom
    .data   : { *(.data*)   } > ram AT > rom
}

построить это

      arm-none-eabi-as --warn --fatal-warnings -mcpu=cortex-m0 flash.s -o flash.o
arm-none-eabi-ld -nostdlib -nostartfiles -T flash.ld flash.o -o so.elf
arm-none-eabi-objdump -D so.elf > so.list
arm-none-eabi-objcopy --srec-forceS3 so.elf -O srec so.srec
arm-none-eabi-objcopy -O binary so.elf so.bin

кот так список

      08000000 <reset-0x8>:
 8000000:   00002000    andeq   r2, r0, r0
 8000004:   08000009    stmdaeq r0, {r0, r3}

08000008 <reset>:
 8000008:   e7fe        b.n 8000008 <reset>

Disassembly of section .bss:

20000000 <.bss>:
    ...

Disassembly of section .data:

20000008 <.data>:
20000008:   11223344            ; <UNDEFINED> instruction: 0x11223344

кошка so.srec

      S00A0000736F2E7372656338
S30F080000000020000009000008FEE7D2
S3090800000A443322113A
S70508000000F2

arm-none-eabi-readelf -l so.elf

      Elf file type is EXEC (Executable file)
Entry point 0x8000000
There are 3 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000094 0x08000000 0x08000000 0x0000a 0x0000a R E 0x2
  LOAD           0x000000 0x20000000 0x0800000a 0x00000 0x00008 RW  0x1
  LOAD           0x00009e 0x20000008 0x0800000a 0x00004 0x00004 RW  0x1

 Section to Segment mapping:
  Segment Sections...
   00     .text 
   01     .bss 
   02     .data 

hexdump -C so.bin

      00000000  00 20 00 00 09 00 00 08  fe e7 44 33 22 11        |. ........D3".|
0000000e

bss обычно не отображается как есть, вы усложняете свой сценарий компоновщика, добавляя начальную и конечную точки, чтобы затем вы могли обнулить этот диапазон в начальной загрузке. Для .data вы можете четко видеть, что происходит, с помощью стандартных инструментов binutils.

Вы не предоставили достаточно кода (и скрипта компоновщика), ни минимального примера, демонстрирующего проблему, так что это все, что можно.

Другие вопросы по тегам