Согласно руководству ld на специальном символе .
, т.е. счетчике местоположения .
Примечание: . фактически относится к байтовому смещению от начала текущего содержащего объекта. Обычно это оператор SECTIONS, начальный адрес которого равен 0. может использоваться как абсолютный адрес. Если . используется внутри описания раздела, однако он относится к байтовому смещению от начала этого раздела, а не к абсолютному адресу. Таким образом, в таком сценарии:
SECTIONS { . = 0x100 .text: { *(.text) . = 0x200 } . = 0x500 .data: { *(.data) . += 0x600 } }
Секции '.text' будет назначен начальный адрес 0x100 и размер точно 0x200 байт, даже если во входных секциях '.text' недостаточно данных для заполнения этой области.
И в руководстве ld также говорится о VMA раздела вывода и LMA:
Каждая загружаемая или выделяемая секция вывода имеет два адреса. Первый - это VMA или адрес виртуальной памяти. Это адрес, который будет иметь секция при запуске выходного файла. Второй - это LMA или адрес загрузочной памяти. Это адрес, по которому будет загружен раздел. В большинстве случаев два адреса будут одинаковыми. Примером, когда они могут быть разными, является то, что раздел данных загружается в ПЗУ, а затем копируется в ОЗУ при запуске программы (этот метод часто используется для инициализации глобальных переменных в системе на основе ПЗУ). В этом случае адресом ПЗУ будет LMA, а адресом ОЗУ - VMA.
Итак, мой вопрос:
Если выходной раздел указан с разными VMA и LMA, какой базовый адрес для байтового смещения .
?
В приведенном ниже примере раздел .data
имеет разные VMA и LMA. Насколько я понимаю, PLACE 1
указывает, что LMA
находится в ROM2
, а PLACE 2
указывает, что VMA
находится в RAM
? Итак, каков базовый адрес символа .
в разделе .data
?
SECTIONS
{
.text :
{
*(.text)
} > REGION_TEXT
.rodata :
{
*(.rodata)
rodata_end = .;
} > REGION_RODATA
.data : AT (rodata_end) <=========== PLACE 1
{
data_start = .;
*(.data)
} > REGION_DATA <=========== PLACE 2
data_size = SIZEOF(.data);
data_load_start = LOADADDR(.data);
.bss :
{
*(.bss)
} > REGION_BSS
}
Схема памяти ниже:
MEMORY
{
ROM : ORIGIN = 0, LENGTH = 2M /*0M ~ 2M*/
ROM2 : ORIGIN = 0x10000000, LENGTH = 1M /*256M ~ 257M*/
RAM : ORIGIN = 0x20000000, LENGTH = 1M /*512M ~ 513M*/
}
REGION_ALIAS("REGION_TEXT", ROM); /*0M ~ 2M*/
REGION_ALIAS("REGION_RODATA", ROM2); /*256M ~ 257M*/
REGION_ALIAS("REGION_DATA", RAM); /*512M ~ 513M*/
REGION_ALIAS("REGION_BSS", RAM); /*512M ~ 513M*/