Почему u-boot может поместить адрес глобальных данных в регистр r9?

Когда я просматриваю исходный код u-boot, я обнаружил, что он передает глобальные данные через регистр r9 следующим образом.

register volatile gd_t *gd asm ("r9")

Итак, мне любопытно, как u-boot гарантирует, что дальнейшие коды не будут использовать регистр r9 и повреждать глобальные данные. Есть ли возможность указать компилятору не использовать определенный регистр?


person demonguy    schedule 17.11.2014    source источник
comment
Также стоит отметить, что раньше он был r8 и до сих пор есть в некоторых ветках вендоров: git.denx.de/   -  person unixsmurf    schedule 17.11.2014


Ответы (2)


Из Стандарт вызова процедур для архитектуры ARM:

Роль регистра r9 зависит от платформы. Виртуальная платформа может назначать этому регистру любую роль и должна документировать это использование. Например, он может обозначать его как статическую базу (SB) в модели данных, не зависящей от позиции, или он может обозначать его как регистр потока (TR) в среде с локальным хранилищем потока. Использование этого регистра может потребовать, чтобы хранимое значение сохранялось во всех вызовах. Виртуальная платформа, которая не нуждается в таком специальном регистре, может назначить r9 в качестве дополнительного регистра переменных, сохраняемых вызываемым пользователем, v6.

Тем не менее, GCC не имеет профиля abi для резервирования r9 для использования платформы. таким образом, u-boot делает это так: с опцией -ffixed-r9.

person auselen    schedule 17.11.2014

Ну, есть -fixed-reg. Однако, если весь код скомпилирован с этой переменной, объявленной глобальной, она никогда не будет использоваться ни для каких других целей (см. https://gcc.gnu.org/onlinedocs/gcc/Global-Reg-Vars.html#Global-Reg-Vars< /а>).

person David Wohlferd    schedule 17.11.2014
comment
Есть ли какая-либо конкретная причина для использования квалификатора типа volatile здесь, в регистре volatile gd_t *gd asm (r9)? память будет выделена для глобальной структуры данных и хранит адрес в указателе gd, который является регистром r9. Таким образом, адрес памяти не будет изменяться асинхронно, предоставленная ссылка gcc также говорит, что не используйте квалификаторы типа, такие как const и volatile. - person user3693586; 13.02.2019
comment
@user3693586 user3693586 - Я не уверен, что я тот человек, которого вы должны спрашивать, поскольку я не рекомендовал использовать volatile. Тем не менее, возможно, что это поможет. Немного. При определенных обстоятельствах. Но поскольку вы не можете зависеть от него (как вы указываете: документы довольно ясны), добавлять его - плохая идея. У людей могут быть ожидания, на которые они полагаются. Если ваш код не будет работать, если он не изменчив, ваш код не будет работать, и вам нужно сделать что-то еще. - person David Wohlferd; 14.02.2019
comment
Спасибо за ответ. У меня есть одно сомнение относительно использования макроса DECLARE_GLOBAL_DATA_PTR, это объявление переменной gd типа gd_t. Этот макрос, используемый в нескольких файлах, означает, что переменная gd была объявлена ​​в нескольких файлах, но тем не менее мы не получили ошибку multiple declarations для переменной gd при компиляции. Из исходного кода U-boot этот макрос используется в common/cli.c, common/cli_readline.c, common/env_common.c, common/board_r.c файлах, и все эти файлы скомпилированы во время сборки. - person user3693586; 21.02.2019
comment
Этот макрос используется в нескольких файлах. Все ли эти файлы используются одновременно? Если один ARM, один MIPS и один x86, конфликта нет, потому что не все они компилируются в один и тот же вывод. - person David Wohlferd; 22.02.2019
comment
Я собрал источник U-boot и проверил. Макрос использовался в нескольких файлах и был скомпилирован. Я имею в виду v2017.3[git.denx.de/ источник. Одним из таких наборов файлов являются common/main.c и common/exports.c. В common/Makefile оба файла выбраны как obj-y += main.o, obj-y += exports.o , что означает, что они скомпилированы и являются частью built-in.o. Другой набор файлов — common/board_f.c и common/board_f.c. - person user3693586; 22.02.2019
comment
Если мы удалим ключевое слово register (#define DECLARE_GLOBAL_DATA_PTR volatile gd_t *gd asm (r9)), то это выдаст ошибку multiple definition of 'r9'. Используя ключевое слово register, он не дает multiple definition of 'r9'error. Не уверен, почему такое поведение. - person user3693586; 22.02.2019