ARM голый металлический многоядерный выбор сердечника
Для многоядерной платформы ARM, например (кластер Cortex-A53 из 4 процессоров):
Как мы можем назначить конкретное ядро для запуска какой-либо функции в качестве базы для написания простого голого планировщика?
Как разные основные ОСРВ реализуют такую функциональность в ARM?
1 ответ
Правильно назначать одно ядро программному обеспечению или несколько ядер программному обеспечению - это не аппаратная конфигурация, которую можно изменить. Все зависит от варианта использования и от того, как протекает программный процесс. Давайте возьмем пример.
Давайте возьмем CortexA53 кластер из 4 ядер. Обычно при запуске запускается плата инициализации прошивки. Как и FSBL(загрузчик первой ступени) в случае zcu102 от xilinx, он также имеет 4 ядра cortexA53. После этого запускается ATF (arm trust firmware), после чего запускается uboot. Все они работают на ядре 0.
Важно: теперь, когда мы запускаем любой бинарный файл с использованием u-boot, он запускается на core 0. Допустим, мы запустили Linux. Теперь после пары инициализаций Linux запустит другие ядра, используя некоторые регистры, специфичные для Soc. Обычно два регистра важны. Когда программное обеспечение на одном ядре хочет запустить другое ядро, оно загрузит программное обеспечение в память, которую оно хочет выполнить на core1, и запрограммирует специальный регистр со своим начальным адресом, а другой специальный регистр выведет его из сброса и core1. начнет выполнять это программное обеспечение.
Таким образом, вы видите, что все зависит от программного обеспечения, которое он хочет использовать другие ядра или нет.
Так что пишите свой код, не опасаясь, что он будет автоматически выполняться другими ядрами, и все будет с треском!!!
Одно из исправлений здесь, для простоты я сказал выше, что linux напрямую использует регистры для запуска других ядер. Это не так в ARM. Мы используем специальные звонки под названием SMC. Эти вызовы отправляются в безопасный мир, где ATF проверяет, какие аргументы передаются для SMC, и выполняет соответствующую службу.
Дополнительный материал: чтобы быстро начать работу, используйте предоставленные поставщиком файлы запуска и напишите простое приложение hello world, открыв его серийный номер, и загрузите его с помощью uboot, выполнив следующую команду
fatload mmc 0:1 0x0 app.bin; go 0x0
Он загрузит ваше приложение с SD-карты и запустит его на core0 по адресу 0x0. Очевидно, вам придется изменить адрес, на который связано ваше приложение, а также номер раздела, указанный после mmc.
Вы забегаете вперед, сначала вам нужно посмотреть, как производитель чипов управляет этими ядрами. Подразделяется на две основные категории: одна - релизы производителя чипов сбрасываются сразу на всех ядрах, другая - сбросы релизов производителя чипов на одном ядре, и это ядро может затем через CSR сбросить сброс на других ядрах. Семейство Raspberry Pi - пример первого, материал на основе Allwinner - пример второго.
Тем не менее, он все еще очень управляем, все ядра будут вводиться в одно и то же место в памяти, адрес исключения сброса, так что вы либо размещаете код, который сортирует ядра с самого начала, либо по мере освобождения каждого ядра вы меняете обработчик сброса где-нибудь так, чтобы направьте каждое новое ядро в новое место. Если вы заглянете на форум raspberry pi baremetal, вы увидите простой код, который делает это и / или просто выводит код, который загрузчик графического процессора помещает в начале arm ram, для сортировки ядер (загрузка без config.txt, который паркует три ядра и пусть core0 запустится, затем поместите туда некоторый код, чтобы core0 мог распечатать через uart содержимое первых десятков слов, разбирать, чтобы вы могли видеть, как они это делают). По сути, каждое ядро имеет уникальный идентификатор, который вы можете использовать для направления выполнения этого ядра на свой собственный код.
Портированная ОС должна делать все это для вас.
Ранние многоядерные процессоры были довольно очевидны, и в техническом справочном руководстве было показано, что каждое ядро имеет свои собственные часы включения и сброса, и поставщик микросхем должен решить, что с ними делать. Более новые ядра и документация имеют этот черный ящик, поэтому я не знаю, как это работает, но знаю, что мы видим оба варианта решения среди производителей чипов. Я считаю, что подход broadcom/pi лучше только потому, что нет скрытых / недокументированных CSR, чтобы найти или выяснить, где, в конце концов, вам придется ждать, пока кто-нибудь взломает это, чтобы выяснить это. Это не значит, что все операторы связи и все победители одинаковы, каждая компания может свободно разрабатывать каждую отдельную деталь, как им нравится, и могут иметь разные решения. Я не удивлюсь, если части, связанные с pi Broadcom, будут иметь управляющий регистр, который возится с графическим процессором, и что мы сможем возиться, если сможем его найти.
Как только вы запустите ядра, нужно просто указать программный счетчик определенного ядра на конкретный адрес. Либо из перезагрузки вы контролируете, где находится это ядро, либо через прерывания или исключения для этого ядра, вы затем возвращаете управление на другой адрес. Не отличается от контроля над одноядерным процессором. Здесь нет магии.