Перейти к содержанию

    

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-а?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Что-то было в документации про 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 в привычном синтаксисе.

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

Изменено пользователем Andrey Vasilyev

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти