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/ загрузочный код, но в любом случае это не будет иметь значения).