ARM: Безопасная позиция физической памяти (для резервирования) для моего гипервизора ARM по отношению к гостю Linux/Android

Я занимаюсь разработкой базового гипервизора на ARM (на плате Arndale Exynos 5250). Я хочу загрузить Linux(Ubuntu или что-то еще)/Android в качестве гостя. В настоящее время я использую дистрибутив Linaro.

Я почти у цели, большинство больших проблем уже решено, за исключением последней: резервирование памяти для моего гипервизора, чтобы ядро ​​не пыталось перезаписать его перед анализом FDT или командной строки ядра.

Проблема в том, что U-Boot моего дистрибутива Linaro передает FDT в R2 ядру Linux, НО ядро пытается перезаписать память моего гипервизора, прежде чем увидит, что я зарезервировал эту область памяти в FDT (декомпилируя DTB, модифицируя DTS и перекомпилировать это). Я пытался изменить параметры командной строки ядра, но они также анализируются ПОСЛЕ того, как ядро ​​пытается перезаписать мою зарезервированную часть памяти.

Таким образом, мне нужно безопасное место в физической памяти, куда я помещаю код моего гипервизора так, чтобы ядро ​​Linux не пыталось получить доступ (r/w) к нему ДО анализа файлов FDT или его командной строки.

Подробности контекста:

  • Структура системной памяти на Exynos 5250: физическая память начинается с 0x4000_0000 (=1 ГБ) и имеет длину 0x8000_0000 (=2 ГБ).
  • Ядро Linux загружается (U-Boot) в 0x4000_7000, его размер (несжатый uImage) составляет менее 5 МБ, а его точка входа установлена ​​в 0x4000_8000;
  • uInitrd загружается в 0x4200_0000 и имеет размер менее 2 МБ
  • FDT (board.dtb) загружается в 0x41f0_0000 (передается в R2) и имеет размер менее 35 КБ
  • В настоящее время я загружаю свой гипервизор по адресу 0x40C0_0000 и хочу зарезервировать 200 МБ (0x0C80_0000), начиная с этого адреса, но ядро ​​пытается выполнить запись туда (ловушка HYP этапа 2 сообщает мне об этом), прежде чем искать в FDT или в командной строке, чтобы увидеть что регион фактически зарезервирован. Если вместо этого я загружаю свой гипервизор в 0x5000_0000 (даже без изменения исходного DTB или командной строки), он не пытается перезаписать меня!
  • FDT передается напрямую, а не через ATAG

Так как при загрузке моего гипервизора в 0x5000_0000 ядро не пытается перезаписать его вообще, я предполагаю, что есть области памяти, которые Linux не затрагивает перед анализом FDT / командной строки. Мне нужно знать, правда это или нет, и, если это правда, некоторые детали, касающиеся этих областей памяти.

Спасибо!

СВЯЗАННЫЙ ВОПРОС:

Кто-нибудь знает, что является приоритетом между следующими: ATAGs / ядро-командная строка / FDT? Например, если я резервирую память через командную строку ядра, но не в FDT (.dtb), она должна работать или командная строка переопределяется FDT? Есть ли какая-то связь между этими тремя?

2 ответа

Решение

Согласно https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/arm/Booting, безопасные расположения начинаются с 128 МБ с момента запуска ОЗУ (при условии, что ядро ​​загружено в этом регион, который должен быть). Если zImage был загружен в память ниже, чем то, что может быть конечным адресом распакованного изображения, он может переместиться выше, прежде чем начнет распаковываться. Но в дополнение к этому у ядра есть область.bss за концом распакованного изображения в памяти.

(Также обратите внимание, что ваши местоположения FDT и initrd уже нарушают эту спецификацию, и что блок памяти, который вы хотите зарезервировать, покрывает местоположения обоих из них.)

Фактически, ваша зарезервированная область должна идти после FDT и initrd в памяти, что равно 0x50000000. Но все, что> 0x08000000 с начала ОЗУ, должно работать, по-видимому, до тех пор, пока это не перезапишет FDT, initrd или U-Boot в памяти.

Приоритет командной строки kernel/FDT/bootloader зависит от конфигурации ядра - выполните настройку меню и проверьте в разделе "Параметры загрузки". Вы можете комбинировать ATAGS со встроенными командными строками, но не FDT - в конце концов, FDT chosen Предполагается, что узел генерируется загрузчиком - поддержка FDT в U-boot в порядке, поэтому вы должны позволить ему сделать это, а не вставлять его в.dts, если вам нужна командная строка FDT.

Ядро довольно консервативно, пока не получило свою карту памяти, так как оно должно слепо верить, что загрузчик выложил все как указано. U-boot, с другой стороны, копирует свои биты повсюду и, безусловно, является виновником верхнего уровня оперативной памяти - если вы #define DEBUG в (я думаю) common/board_f.c вы получите дамп того, что он ударил во время перемещения (не включая Exynos iRAM SPL/ загрузочный код, но в любом случае это не будет иметь значения).

Другие вопросы по тегам