diff options
Diffstat (limited to 'ru-ru')
| -rw-r--r-- | ru-ru/linker-ru.html.markdown | 203 | 
1 files changed, 203 insertions, 0 deletions
| diff --git a/ru-ru/linker-ru.html.markdown b/ru-ru/linker-ru.html.markdown new file mode 100644 index 00000000..7df29c23 --- /dev/null +++ b/ru-ru/linker-ru.html.markdown @@ -0,0 +1,203 @@ +--- +category: tool +tool: linker +contributors: +    - ["Alexander Kovalchuk", "https://github.com/Zamuhrishka"] +translators: +    - ["Alexander Kovalchuk", "https://github.com/Zamuhrishka"] +lang: ru-ru +--- + +# Основные понятия и определения +**Счетчик позиций** - у компоновщика есть специальная переменная  +"." (точка) всегда содержит текущую позицию вывода. + +# Функции +**ADDR(section)** -  возвращает абсолютный адрес указанной секции. Однако  +данная секция должна быть определенна до использования функции ADDR. + +**ALIGN(exp)** -  возвращает значение счетчика позиций, выравненное на границу  +следующего за exp выражения. + +**SIZEOF(section)** -  возвращает размер секции в байтах. + +**FILL(param)** -  определяет образец заполнения для текущей секции. Все  +остальные неуказанные регионы внутри секции заполняются значением указанными  +в аргументе функции. + +**KEEP(param)** -  используется чтобы помечать param как неустранимый. + +**ENTRY(func)** -  определяет функцию, которая будет являться точкой входа  +в программу. + +```bash +# Определяем точку входа в программу +ENTRY(Reset_Handler) + +# Определяем перемнную которая содержит адрес вершины стека +_estack = 0x20020000;   +# Определяем перемнную которая содержит значение размера кучи   +_Min_Heap_Size = 0x200; +# Определяем перемнную которая содержит значение размера стека +_Min_Stack_Size = 0x400;  + +# Описание карты памяти доступной для данного процессора +# MEMORY +# { +# ИМЯ_ОБЛАСТИ_ПАМЯТИ	(права доступа)	: ORIGIN = АДРЕС_НАЧАЛА, LENGTH = РАЗМЕР +# } +# В нашем примере контроллер содержит три области памяти: +# RAM - начинается с адреса 0x20000000 и занимает 128 Кбайт; +# CCMRAM - начинается с адреса 0x10000000и занимает 64 Кбайт; +# FLASH - начинается с адреса 0x8000000 занимает 1024 Кбайт; +# Причем RAM память доступка для чтения, записи и исполнения. +# CCMRAM память доступна только на чтение и запись. +# FLASH память доступна на чтение и исполнение. +MEMORY +{ +	RAM 		(xrw)     : 	ORIGIN = 0x20000000, 	LENGTH = 128K +	CCMRAM 		(rw)      : 	ORIGIN = 0x10000000, 	LENGTH = 64K +	FLASH 		(rx)      : 	ORIGIN = 0x8000000, 	LENGTH = 1024K +} + +# Описываем выходные секции +SECTIONS +{ +	# Первая секция содержит таблицу векторов прерываний +  .isr_vector : +  { +	# Выравниваем текущую позицию на границу 4-х байт. +    . = ALIGN(4); + +	# Существует опция --gc-sections, которая позволяет собирать мусор из неиспользуемых  +	# входных разделов. И если есть разделы, которые сборщик муссора не должен трогать,  +	# то их необходимо указать в качестве аргумента функции KEEP() (аналог ключевого слова  +	# volatile). +	# Запись (*(.isr_vector)) означает разделы .isr_vector во всех объектных файлах. Т.к.  +	# обращение к разделу в общем виде выглядит так: (ИМЯ_ФАЙЛА(ИМЯ_РАЗДЕЛА))	 +    KEEP(*(.isr_vector))     + +	# Выравниваем текущую позицию на границу 4-х байт. +    . = ALIGN(4); +	 +	# Выражение ">ОБЛАСТЬ_ПАМЯТИ" указывает в какую именно область памяти будет помещенна  +	# данная секция.	В нашем слущае секция .isr_vector будет размещена во FLASH памяти. +  } >FLASH + +# ИТОГО: Секция .isr_vector, которая содержит таблицу векторов прерываний выравнивается  +# по границе 4-х байт, помечается как недоступная для сборщика мусора и размещается в начале  +# FLASH памяти микроконтроллера. + +  # Вторая секция содержит код программы. +  .text : +  { +	# Выравниваем текущую позицию на границу 4-х байт. +    . = ALIGN(4); +     +    # Указываем, что в данной секции будут хранится области .text всех +	# объектных файлов    +    *(.text)            +    *(.text*)           + +	# Защищаем от сборщика мусора секции .init и .fini +    KEEP (*(.init)) +    KEEP (*(.fini)) + +	# Выравниваем текущую позицию на границу 4-х байт. +    . = ALIGN(4); +     +	# Определяется переменная _etext, которая хранит в себе адрес конца секции .text и которая +	# может быть доступна в исходном тексте программы через объявление  +	# volaile unsigned int extern _etext; +    _etext = .;       +  } >FLASH +   +# ИТОГО: Секция .text, которая содержит код программы выравнивается по границе 4-х байт,  +# включает в себя: все секции с кодом программы во всех объектных файлах и защищенные  +от сборщика муссора секции .init и .fini во всех объектных файлах, распологается во FLASH  +памяти микроконтроллера сразу за таблицей векторов.  +Секции text, .init и .fini. располагаются в памяти в той последовательности в которой они  +объявлены в скрипте. + +  # Третья секция содержит константные данные. +  .rodata : +  { +	# Выравниваем текущую позицию на границу 4-х байт. +    . = ALIGN(4); + +	# Указываем, что в данной секции будут хранится области .rodataвсех +	# объектных файлов    +    *(.rodata)          +    *(.rodata*)   +     +	# Выравниваем текущую позицию на границу 4-х байт.       +    . = ALIGN(4); +  } >FLASH +   +  # Сохраняем в переменной _sidata  абсолютный адрес секции .data +  _sidata = LOADADDR(.data); + +  # Четвертая секция содержит инициализированные переменные. +  .data :  +  { +	# Выравниваем текущую позицию на границу 4-х байт. +    . = ALIGN(4); + +	# Сохраняем в переменной _sdata адрес текущей позиции (начала секции) +    _sdata = .;      +   +	# Указываем, что в данной секции будут хранится области .data всех +	# объектных файлов      +    *(.data)            +    *(.data*)           + +	# Выравниваем текущую позицию на границу 4-х байт. +    . = ALIGN(4); +     +    # Сохраняем в переменной _sdata адрес текущей позиции (конец секции) +    _edata = .;     +    +	# Функция AT указывает на то, что данный сектор хранится в одной области памяти  +	# (в нашем случае FLASH), а исполняться будет из другой обасти памяти (в нашем случае RAM).  +	# Есть два типа адрессов: +	# * VMA (Virtual memory address) - это run-time адрес по которому уомпилятор ожидает  +	#	видеть данные. +	# * LMA (Load memory address) - это адрес по которому линкер хранит данные.			 +			 +	#Startup должен код скопировать секцию .data из адрессов LMA в адресса VMA. +	 +  } >RAM AT> FLASH + +  # Пятая секция содержит инициализированные нулем переменные.   +  .bss : +  { +	# Сохраняем в переменной _sbss и __bss_start__  адрес текущей позиции (начала секции) +    _sbss = .;         +    __bss_start__ = _sbss; +     +	# Указываем, что в данной секции будут хранится области .bss всех +	# объектных файлов  +    *(.bss) +    *(.bss*) + +	# Выравниваем текущую позицию на границу 4-х байт. +    . = ALIGN(4); +     +    # Сохраняем в переменной _ebss и __bss_end__ адрес текущей позиции (начала секции) +    _ebss = .;          +    __bss_end__ = _ebss; +  } >RAM + +  # Шестая секция содержит кучу и стек. Размещается в самом конце RAM. +  ._user_heap_stack : +  { +    . = ALIGN(4); +    PROVIDE ( end = . ); +    PROVIDE ( _end = . ); +    . = . + _Min_Heap_Size; +    . = . + _Min_Stack_Size; +    . = ALIGN(4); +  } >RAM +} +``` + | 
