реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> GNU ld: хочу странного: разместить перекрывающиеся секции
Andrey Vasilyev
сообщение Apr 8 2018, 16:02
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 46
Регистрация: 5-12-08
Из: Санкт-Петербург
Пользователь №: 42 220



Коллеги, здравствуйте

Прошу помощи от гуру, хорошо разбирающихся в GNU ld.

Поднимаю сейчас компиляцию нашей софтины под странную платформу. Ее особенность - все исполнение идет из RAM, причем RAM там разделено на 4 куска по полмегабайта, и 3 из 4 кусков поддерживают доступ только двойными словами: при попытке обратиться как к байту или как к полуслову вылетает data abort.
Если быть точным, это не платформа странная, а я от нее хочу странного - пытаюсь заиспользовать память DSP-шных ядер для чего-то полезного, ибо сами эти ядра нам не нужны.

Первого полумегабайта нам совсем не хватает под все наши нужды, поэтому сделал следующее:
1. У нас довольно много данных в .bss, к которым идет обращение только словами, и я их вынес в отдельную секцию, назвал которую .bss32bit (и размещаю ее в той части памяти, которая чисто 32-битная)
2. Код собираю в 32-битном режиме ARM, а не в Thumb, и разместил его тоже в чисто-32-битном блоке

В итоге, вроде бы все прекрасно - под .data и .bss в первом блоке места достаточно, и остается еще прилично места под кучу.
Но тут вылезает еще одно неудобство: простым образом при старте можно загрузить снаружи бинарник только в первый блок, и соответственно, хочется стартовать оттуда, в startup-е перемещая .text куда нужно и очищая оба .bss-а как обычно. Этакое исполнение из flash-а наоборот - не .data перемещается, а .text.
Реализовал это все, и даже все работает - после старта .text копируется во второй блок, .bss очищается, .bss32bit тоже очищается, передается управление на main, и дальше все работает.

Но после перемещения .text место из-под него в первом блоке уже свободно, и хотелось бы переиспользовать его под .bss (сейчас там располагается куча, но .bss у нас тоже большой).
Пытаюсь понять про оверлеи в доке ld, но там указано, что для секций внутри оверлея нельзя указать LMA и/или VMA, они указываются только для самой оверлейной области.

Понимаю, что можно решить задачу грубой силой - .text при линковке вообще выносить в отдельный файл и при старте стартапным кодом сразу грузить его снаружи прямо в нужную память. Но очень уж не хочется такого монстра в стартапном коде городить...

Может быть, кто-то может подсказать какой-то трюк, который все-таки позволит слинковать .bss в ту же память, которая была LMA .text-а?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 8 2018, 17:05
Сообщение #2


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Что-то было в документации про overlay, мне не нужно было никогда, я не изучал вопрос глубоко. Может вам подойдет?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Andrey Vasilyev
сообщение Apr 8 2018, 19:46
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 46
Регистрация: 5-12-08
Из: Санкт-Петербург
Пользователь №: 42 220



Цитата(Сергей Борщ @ Apr 8 2018, 20:05) *
Что-то было в документации про overlay, мне не нужно было никогда, я не изучал вопрос глубоко. Может вам подойдет?

Там вот такое написано:
The section definitions within the OVERLAY construct are identical to those within the general SECTIONS construct (see SECTIONS), except that no addresses and no memory regions may be defined for sections within an OVERLAY.
No memory regions - значит, VMA изменить не получится, если я правильно понял.
Но я в этом всем плаваю, так что еще остается надежда, что есть какой-то очевидный способ, которого я просто не вижу sm.gif


ДОПОЛНЕНИЕ:

Вроде бы получилось. Последний абзац раздела ld-шной доки про оверлеи натолкнул на мысль.
Еще надо проверять, но в map-файле все выглядит красиво, и вдобавок запускается минимальный пример.

Что сделал:
CODE
.text 0x100000 : AT ( _edata ) { ... }
.bss _edata ( NOLOAD ) : { ... }

_edata - это символ, которому присвоен location counter после конца .data, а 0x100000 - это адрес того блока памяти, куда при старте копируется .text и из которого работает.

В map-файле получилось вот что:
CODE
0x00000000c0000490 _edata = .
...
.text 0x0000000000100000 0x7b58 load address 0x00000000c0000490
...
.bss 0x00000000c0000490 0x128 load address 0x000000017ff00920
...

0xC0000000 - это физический адрес основного блока памяти, из которого стартуем и где остается .data

Похоже, ld-шные ограничения не сработали, так как одна из перекрывшихся по LMA секций оказалась NOLOAD (и чего я мучился - оно с самого начала могло так заработать...).

Синтаксис еще покручу - это только затравка, некрасивый, но приведший к результату пример. Как минимум вместо 0x100000 сделаю нормальное назначение VMA в привычном синтаксисе.
Надеюсь, я по запарке не пропустил чего-то важного - например, не залил при проверке какой-то другой бинарник sm.gif

Сообщение отредактировал Andrey Vasilyev - Apr 8 2018, 19:51
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th April 2024 - 16:56
Рейтинг@Mail.ru


Страница сгенерированна за 0.01373 секунд с 7
ELECTRONIX ©2004-2016