Компоновщик: перемещение всех функций, кроме двух, в определенную область памяти.

Я работаю над прошивкой для микроконтроллера PIC32MX. Память программы должна быть разделена на три сегмента:

  • Раздел 1: процедура обслуживания прерывания и основная функция (startup_region)
  • Раздел 2: 50% оставшейся программной памяти (program1)
  • Раздел 3: 50% оставшейся программной памяти (program2)

Прошивка хранится только в разделе 2 или 3. Другой зарезервирован для будущих обновлений. Таким образом, активная область может безопасно переопределить другую для хранения обновления. Бит конфигурации перевернут, и функция main() раздела 0 теперь переходит к другой программе при перезагрузке.

Таким образом, мне нужно, чтобы компоновщик поместил все функции, кроме isr и main, в раздел 1, а все остальное — в раздел 2. Раздел 3 нужно оставить полностью пустым, так как в будущем он может быть переопределен.

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

linkerscript.ld:

/* [...] */
INCLUDE procdefs.gld
/* [...] */
SECTIONS
{
  /* [...] */
  .text :
  {
    /* isr() and main() should be at the very first locations in program memory */
    *(.text.isr)
    *(.text.main)
    /* [...] */
    . = ALIGN(4) ;
  } >kseg0_program_mem

  .program1 :
  {
    *(*.text)
  } >program1

  /* [...] */
}

procdefs.gld:

/* [...] */
MEMORY
{
  kseg0_program_mem     (rx)  : ORIGIN = 0x9D000000, LENGTH = 0x10000
  startup_region        (rx)  : ORIGIN = 0x9D000000, LENGTH = 0x01000
  program1              (rx)  : ORIGIN = 0x9D002000, LENGTH = 0x07000
  program2              (rx)  : ORIGIN = 0x9D009000, LENGTH = 0x07000
  kseg0_boot_mem              : ORIGIN = 0x9FC00490, LENGTH = 0x970
  /* [...] */
}
/* [...] */

Это приводит к следующему:

isr() и main() там, где они должны быть (0x9D00000 - виртуальный адрес KSEG0 начала прошивки программы)

.text           0x9d000000       0x94
 *(.text.isr)
 .text.isr      0x9d000000       0x60 build/default/production/main.o
                0x9d000000                isr
 *(.text.main)
 .text.main     0x9d000060       0x34 build/default/production/main.o
                0x9d000060                main

Область program1 размещена правильно, и большинство объектных файлов перечислены правильно (заметьте, однако, что main.o указан снова — он уже использовался).

.program1       0x9d002000      0xc44
 *(*.text)
 .text          0x9d002000        0x0 /opt/microchip/xc32/v2.10/bin/bin/../../lib/gcc/pic32mx/4.8.3/../../../../pic32mx/lib/./proc/32MX330F064H/crt0_mips32r2.o
 .text          0x9d002000        0x0 /opt/microchip/xc32/v2.10/bin/bin/../../lib/gcc/pic32mx/4.8.3/../../../../pic32mx/lib/debug-exception-return.o
 .text          0x9d002000        0x0 build/default/production/main.o
 .text          0x9d002000        0x0 build/default/production/commands.o
 /* [...] */
 .text          0x9d002000        0x0 build/default/production/micro-ecc/uECC.o

Однако некоторые функции расположены за пределами этой области:

.text.uECC_verify
                0x9d000b04      0x7c0
 .text.uECC_verify
                0x9d000b04      0x7c0 build/default/production/micro-ecc/uECC.o
                0x9d000b04                uECC_verify

.text.vli_mmod_fast_secp256r1
                0x9d0012c4      0x520
 .text.vli_mmod_fast_secp256r1
                0x9d0012c4      0x520 build/default/production/micro-ecc/uECC.o

Я не понимаю, почему это происходит.

Мои вопросы:

  • Как я могу заставить компоновщик поместить все функции (кроме main и isr) в program1.
  • Как мне запретить компоновщику что-либо класть в program2, чтобы он оставался свободным.

Я компилирую ПО с переключателем -ffunction-segments, чтобы каждой функции достался свой сегмент.

Оригинальный линкерскрипт также содержит подозрительный комментарий:

/* Code Sections - Note that input sections *(.text) and *(.text.*)
   are not mapped here. Starting in C32 v2.00, the best-fit allocator
   locates them, so that .text may flow around absolute sections
   as needed.
*/

person Danish    schedule 19.02.2020    source источник
comment
Разве это не должно быть *(.text.*) в разделе .program1?   -  person Ctx    schedule 20.02.2020
comment
Ты прав! Теперь он работает нормально.   -  person Danish    schedule 20.02.2020


Ответы (1)


Объектный файл main.o не совпадает с сегментом памяти функции .tex.main. Если этот объектный файл создает какие-то другие текстовые сегменты, они будут размещены в другом месте. Это то, что вы видите в файле карты.

Как упомянул @Ctx, синтаксис вашего текстового сегмента неверен, вместо *(*.text) он должен быть

  .program1 :
  {
    *(.text*)
  } >program1

Таким образом, все остальные текстовые сегменты будут правильно размещены в памяти program1.

person Teivaz    schedule 20.02.2020