Я пытаюсь создать и связать один образ для загрузки в качестве ядра ОС (т.е. в QEMU), ориентируясь на aarch64-unknown-none-softfloat. Я использую собственный файл linker.ld, который устанавливает точку входа для ядра ENTRY(_reset)
и позиционирует изображение
. = 0x40080000
где программный счетчик (ПК) находится в состоянии сброса.
Это работает нормально, пока я не сопоставлю страницы по адресу 0x40080000 с верхней памятью, где будет находиться ядро, и не включу преобразование виртуальной памяти. Чтобы отладочная информация совпадала после переключения, я изменяю номинальное положение изображения на
. = 0xffffff8200000000
и восстановить.
Я обнаружил, что доступ:
- к некоторой (внешней пабе) статике, и
- некоторыми функциями основной библиотеки
заключается в чтении абсолютного адреса откуда-то из .rodata
. Это ломает код, когда он запускается до сопоставления. И если я верну его обратно, это сломает код, когда я запущу его после сопоставления.
Код, который он генерирует, выглядит примерно так на O1 (косвенно через страницу, относящуюся к ПК):
adrp x0, 0x10000 // page offset from PC up to rodata
add x0, 0x120 // byte offset from page in rodata
ldr x0, [x0] // use as address
Что мне нужно, так это действительно позиционно независимый код в коде и данных, чтобы он работал в обоих местах в памяти, не обращаясь к каким-либо сохраненным абсолютным адресам, даже если эти адреса доступны относительно ПК.
Я пробовал другие модели перемещения, включая Pic и RopiRwpi, но не вижу, чтобы они генерировали другой код.
Спасибо!
РЕДАКТИРОВАТЬ: Большое спасибо за предложения по временной карте. Я видел, что используется. Меня больше интересуют параметры компилятора, которые позволят -no-dynamic-linker работать, избегая генерации кода, требующего перемещения R_AARCH64_ABS64, в силу гарантии того, что код и данные будут находиться на заданном расстоянии друг от друга.