Jump to content

    

GNU ld: хочу странного: разместить перекрывающиеся секции

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

 

Прошу помощи от гуру, хорошо разбирающихся в 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-а?

 

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
Что-то было в документации про 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 изменить не получится, если я правильно понял.

Но я в этом всем плаваю, так что еще остается надежда, что есть какой-то очевидный способ, которого я просто не вижу :)

 

 

ДОПОЛНЕНИЕ:

 

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

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

 

Что сделал:

.text 0x100000 : AT ( _edata ) { ... }
.bss _edata ( NOLOAD ) : { ... }

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

 

В map-файле получилось вот что:

                0x00000000c0000490                _edata = .
...
.text           0x0000000000100000     0x7b58 load address 0x00000000c0000490
...
.bss            0x00000000c0000490      0x128 load address 0x000000017ff00920
...

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

 

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

 

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

Надеюсь, я по запарке не пропустил чего-то важного - например, не залил при проверке какой-то другой бинарник :)

Edited by Andrey Vasilyev

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now