Файл карты компоновщика GNU, дающий неожиданные адреса загрузки
Я работаю над встроенной программой, где у меня есть собственный скрипт компоновщика. Программа работает, но я заметил, что, возможно, что-то не так с тем, как компоновщик размещает пару разделов в памяти.
Вот соответствующие части скрипта компоновщика:
MEMORY {
ROM (rx) : ORIGIN = 0x00100000, LENGTH = 16k
RAM (rwx) : ORIGIN = 0x00200000, LENGTH = 4k
}
SECTIONS {
/* Other sections go here. */
.data : {
...
} >RAM AT>ROM
.bss : {
...
} >RAM
.stack : {
...
} >RAM
...
}
А вот соответствующая часть файла MAP:
.data 0x00200040 0x0 load address 0x001003d4
0x001003d4 __data_load = LOADADDR (.data)
0x00200040 __data_start = .
*(.data)
*(.data*)
0x00200040 . = ALIGN (0x4)
0x00200040 _edata = .
.igot.plt 0x00200040 0x0 load address 0x001003d4
.igot.plt 0x00000000 0x0 ./debug/sam7s_startup.o
.bss 0x00200040 0x0 load address 0x001003d4
0x00200040 __bss_start__ = .
*(.bss)
*(.bss*)
*(COMMON)
0x00200040 . = ALIGN (0x4)
0x00200040 _ebss = .
0x00200040 __bss_end__ = .
0x00200040 PROVIDE (end, _ebss)
0x00200040 PROVIDE (_end, _ebss)
0x00200040 PROVIDE (__end__, _ebss)
.stack 0x00200040 0x200 load address 0x001003d4
0x00200040 __stack_start__ = .
Поэтому из файла карты мне кажется, что секции .bss и .stack получают адреса загрузки в ПЗУ. Я думаю, что это из-за этих двух строк:
.bss 0x00200040 0x0 load address 0x001003d4
.stack 0x00200040 0x200 load address 0x001003d4
Это н'это хорошо, потому чтонет смысла в том, чтобы они занимали место в ПЗУ. Раздел .bss, хотя и сейчас пустой, будет содержать неинициализированные глобальные переменные, которые будут установлены в ноль в коде. Стек также является лишь частью оперативной памяти, которая будет инициализирована в коде. Так что'Нет необходимости, чтобы какой-либо из этих разделов занимал место в ПЗУ.
Итак, мой вопрос: как правильно остановить загрузку .bss и .stack в ПЗУ? Должен ли я изменить конец разделов .bss и .stack с>RAM
в>RAM AT>RAM
? Это кажется немного излишним.
После тестирования некоторых вещей я обнаружил следующее:
(1) Использование(NOLOAD)
атрибут (например, путем замены.stack :
с.stack (NOLOAD) :
) по-прежнему приводит к файлу карты, показывающему адрес загрузки ПЗУ для секций .stack и .bss.
(2) УказаниеRAM AT>RAM
как упоминалось выше, действительно не дает выводу карты отображать адреса загрузки ПЗУ для секций .stack и .bss.
(3) Когда файл карты показывает адреса загрузки для разделов .bss и .stack, оказывается, что они фактически не занимают место в ПЗУ. Раздел .stack, хотя и имеет длину 0x200 байт, похоже, фактически не занимает это пространство в ПЗУ, даже если я задаю для него значения заполнения и помещаю раздел после него в сценарии компоновщика. Раздел, следующий за ним в скрипте компоновщика, не перемещается с различными размерами стека.
Так что, возможно, вывод файла карты нея не имею в виду то, что я думаю, а секции .stack и .bss неНа самом деле, вообще, адреса загрузки в ПЗУ. После того, как вы попробуете несколько вещей, это наверняка будет выглядеть так. Было бы все еще интересно узнать, почему вывод карты выглядит так, как будто разделы получают адреса загрузки ПЗУ, особенно когда(NOLOAD)
используется. Может ли это быть просто ошибкой в том, как LD генерирует свои выходные файлы карты?
Смотрите также:Понимание счетчика местоположений сценариев GNU Linker