ЛР13. Исправление скрипта компоновщика

This commit is contained in:
Andrei Solodovnikov
2023-12-11 16:45:48 +03:00
parent 7626efc394
commit 26b0f592f5
2 changed files with 100 additions and 25 deletions

View File

@@ -95,25 +95,48 @@ ENTRY(_start) /* мы сообщаем компоно
находится у метки "start"
*/
/*
Объявляем вспомогательные глобальные переменные
*/
_text_size = 0x4000; /* Размер памяти инстр.: 16KiB */
_data_base_addr = 0x8000; /* Стартовый адрес секции данных */
_data_size = 0x4000; /* Размер памяти данных: 16KiB */
_text_size = 0x4000; /* Размер памяти инстр.: 16KiB */
_data_base_addr = 0x4000; /* Стартовый адрес секции данных */
_data_size = 0x4000; /* Размер памяти данных: 16KiB */
_data_end = _data_base_addr + _data_size;
_trap_stack_size = 2560; /* Размер стека обработчика перехватов.
_trap_stack_size = 2560; /* Размер стека обработчика перехватов.
Данный размер позволяет выполнить
до 32 вложенных вызовов при обработке
перехватов.
*/
*/
_stack_size = 1280; /* Размер программного стека.
_stack_size = 1280; /* Размер программного стека.
Данный размер позволяет выполнить
до 16 вложенных вызовов.
*/
*/
/*
В данном разделе указывается структура памяти:
Сперва идет регион "rom", являющийся read-only памятью с исполняемым кодом
(об этом говорят атрибуты 'r' и 'x' соответственно). Этот регион начинается
с адреса 0x00000000 и занимает _text_size байт.
Далее идет регион "ram", начинающийся с адреса _data_base_addr и занимающий
_data_size байт. Этот регион является памятью, противоположной региону "ram"
(в том смысле, что это не read-only память с исполняемым кодом).
*/
MEMORY
{
rom (rx) : ORIGIN = 0x00000000, LENGTH = _text_size
ram (!rx) : ORIGIN = _data_base_addr, LENGTH = _data_size
}
/*
В данном разделе описывается размещение программы в памяти.
Программа разделяется на различные секции:
- секции исполняемого кода программа;
- секции статических переменных и массивов, значение которых должно быть
"вшито" в программу;
и т.п.
*/
SECTIONS
{
PROVIDE( _start = 0x00000000 ); /* Позиция start в памяти
@@ -137,23 +160,31 @@ SECTIONS
секция .text итогового файла, которая состоит из секций .boot, а также всех
секций, начинающихся на .text во всех переданных компоновщику двоичных
файлах.
Дополнительно мы указываем, что данная секция должна быть размещена в
регионе "rom".
*/
.text : {*(.boot) *(.text*)}
.text : {*(.boot) *(.text*)} >rom
/*
Поскольку мы не знаем суммарного размера получившейся секции, мы проверяем
что не вышли за границы памяти инструкций и переносим счетчик адресов за пределы. Памяти инструкций в область памяти данных
что не вышли за границы памяти инструкций и переносим счетчик адресов за
пределы памяти инструкций в область памяти данных.
Дополнительно мы указываем, что данная секция должна быть размещена в
регионе "ram".
*/
ASSERT(. < _text_size, ".text section exceeds instruction memory size")
. = _data_base_addr;
/*
Следующая команда сообщает, что начиная с адреса, которому в данных момент
равен счетчик адресов (_data_base_addr) будет находиться секция .data итогового файла, которая состоит из секций всех секций, начинающихся
равен счетчик адресов (_data_base_addr) будет находиться секция .data
итогового файла, которая состоит из секций всех секций, начинающихся
на .data во всех переданных компоновщику двоичных файлах.
Дополнительно мы указываем, что данная секция должна быть размещена в
регионе "ram".
*/
.data : {*(.data*)}
.data : {*(.data*)} >ram
/*
Общепринято присваивать GP значение равное началу секции данных, смещенное
@@ -171,7 +202,8 @@ SECTIONS
/*
Поскольку мы не знаем суммарный размер всех используемых секций данных,
перед размещением других секций, необходимо выравнять счетчик адресов по 4х-байтной границе.
перед размещением других секций, необходимо выравнять счетчик адресов по
4х-байтной границе.
*/
. = ALIGN(4);
@@ -197,9 +229,12 @@ SECTIONS
указывающие на начало и конец bss-секции посредством счетчика адресов.
Подробнее:
https://en.wikipedia.org/wiki/.bss
Дополнительно мы указываем, что данная секция должна быть размещена в
регионе "ram".
*/
_bss_start = .;
.bss : {*(.bss*)}
.bss : {*(.bss*)} >ram
_bss_end = .;
@@ -213,7 +248,8 @@ SECTIONS
стека от наложения на него стека прерываний.
Однако перед этим, мы должны убедиться, что под программный стек останется
хотя бы 1280 байт (ничем не обоснованное число, взятое с потолка).
Такое значение обеспечивает до 16 вложенных вызовов (если сохранять только необерегаемые регистры).
Такое значение обеспечивает до 16 вложенных вызовов (если сохранять только
необерегаемые регистры).
=================================
*/

View File

@@ -6,7 +6,7 @@ ENTRY(_start) /* мы сообщаем компоно
*/
_text_size = 0x4000; /* Размер памяти инстр.: 16KiB */
_data_base_addr = 0x8000; /* Стартовый адрес секции данных */
_data_base_addr = 0x4000; /* Стартовый адрес секции данных */
_data_size = 0x4000; /* Размер памяти данных: 16KiB */
_data_end = _data_base_addr + _data_size;
@@ -21,6 +21,32 @@ _stack_size = 1280; /* Размер программного
Данный размер позволяет выполнить
до 16 вложенных вызовов.
*/
/*
В данном разделе указывается структура памяти:
Сперва идет регион "rom", являющийся read-only памятью с исполняемым кодом
(об этом говорят атрибуты 'r' и 'x' соответственно). Этот регион начинается
с адреса 0x00000000 и занимает _text_size байт.
Далее идет регион "ram", начинающийся с адреса _data_base_addr и занимающий
_data_size байт. Этот регион является памятью, противоположной региону "ram"
(в том смысле, что это не read-only память с исполняемым кодом).
*/
MEMORY
{
rom (rx) : ORIGIN = 0x00000000, LENGTH = _text_size
ram (!rx) : ORIGIN = _data_base_addr, LENGTH = _data_size
}
/*
В данном разделе описывается размещение программы в памяти.
Программа разделяется на различные секции:
- секции исполняемого кода программа;
- секции статических переменных и массивов, значение которых должно быть
"вшито" в программу;
и т.п.
*/
SECTIONS
{
PROVIDE( _start = 0x00000000 ); /* Позиция start в памяти
@@ -44,23 +70,31 @@ SECTIONS
секция .text итогового файла, которая состоит из секций .boot, а также всех
секций, начинающихся на .text во всех переданных компоновщику двоичных
файлах.
Дополнительно мы указываем, что данная секция должна быть размещена в
регионе "rom".
*/
.text : {*(.boot) *(.text*)}
.text : {*(.boot) *(.text*)} >rom
/*
Поскольку мы не знаем суммарного размера получившейся секции, мы проверяем
что не вышли за границы памяти инструкций и переносим счетчик адресов за пределы. Памяти инструкций в область памяти данных
что не вышли за границы памяти инструкций и переносим счетчик адресов за
пределы памяти инструкций в область памяти данных.
Дополнительно мы указываем, что данная секция должна быть размещена в
регионе "ram".
*/
ASSERT(. < _text_size, ".text section exceeds instruction memory size")
. = _data_base_addr;
/*
Следующая команда сообщает, что начиная с адреса, которому в данных момент
равен счетчик адресов (_data_base_addr) будет находиться секция .data итогового файла, которая состоит из секций всех секций, начинающихся
равен счетчик адресов (_data_base_addr) будет находиться секция .data
итогового файла, которая состоит из секций всех секций, начинающихся
на .data во всех переданных компоновщику двоичных файлах.
Дополнительно мы указываем, что данная секция должна быть размещена в
регионе "ram".
*/
.data : {*(.data*)}
.data : {*(.data*)} >ram
/*
Общепринято присваивать GP значение равное началу секции данных, смещенное
@@ -78,7 +112,8 @@ SECTIONS
/*
Поскольку мы не знаем суммарный размер всех используемых секций данных,
перед размещением других секций, необходимо выравнять счетчик адресов по 4х-байтной границе.
перед размещением других секций, необходимо выравнять счетчик адресов по
4х-байтной границе.
*/
. = ALIGN(4);
@@ -104,9 +139,12 @@ SECTIONS
указывающие на начало и конец bss-секции посредством счетчика адресов.
Подробнее:
https://en.wikipedia.org/wiki/.bss
Дополнительно мы указываем, что данная секция должна быть размещена в
регионе "ram".
*/
_bss_start = .;
.bss : {*(.bss*)}
.bss : {*(.bss*)} >ram
_bss_end = .;
@@ -120,7 +158,8 @@ SECTIONS
стека от наложения на него стека прерываний.
Однако перед этим, мы должны убедиться, что под программный стек останется
хотя бы 1280 байт (ничем не обоснованное число, взятое с потолка).
Такое значение обеспечивает до 16 вложенных вызовов (если сохранять только необерегаемые регистры).
Такое значение обеспечивает до 16 вложенных вызовов (если сохранять только
необерегаемые регистры).
=================================
*/