ARMEmbedded Linux

Jailhouse гипервизор часть 1

Опубликовано

jailhouse

Гипервизор (в рамках данной статьи гипервизор jailhouse) — программа или аппаратная схема, обеспечивающая или позволяющая одновременное, параллельное выполнение нескольких операционных систем на одном и том же хост-компьютере. Гипервизор также обеспечивает изоляцию операционных систем друг от друга, защиту и безопасность, разделение ресурсов между различными запущенными ОС и управление ресурсами[1].

Обзор jailhouse

(назвали тюрьмой, если переводить с английской, подчеркивая раздельное выполнение каждой из ОС).

Jailhouse — статический гипервизор разбиения, который запускает bare metal бинари. Он близко взаимодействует с Linux.  Jailhouse не эмитирует ресурсы, которые не существуют. Он только разбивает существующие аппаратные ресурсы на изолированные отсеки, которые называются клеткам (как в тюрьме) — «cells», данная особенность полностью предназначена чтобы гостевое программное обеспечение было изолировано, такое изолированное программное обеспечение называется заключенным — «inmate». Одна из cell запускается на ОС Linux. Другие cell занимают CPU и устройства из root (корневой) cell, когда они создаются.

На рисунке выше показан jailhouse на ОС Linux. a) Linux до включения jailhouse б) После включения jailhouse в) Linux после создания cell.

Jailhouse состоит из 3 частей: модуль ядра (драйвер), прошивка гипервизора и инструменты, которые пользователь использует чтобы включить гипервизор, создать cell, загрузить inmate бинарь, запустить и остановить. Jailhouse это пример асинхронной мультипроцессорной архитектуры (AMP). Когда вы загружаетe linux на AM57xx-EVM, который имеет 2 arm ядра, linux использует оба ядра (SMP). После разрешения (включения) гипервизора, гипервизор переводит linux на корневую cell. Корневая cell по прежнему использует оба ядра arm. Когда вы создаете новую cell, гипервизор вызывает cpu_down() для arm1 ядра (на рисунке cpu 0), оставляя для linux только arm0. Новая cell будет исполняться на arm1 ядре и аппаратные ресурсы предназначены для cell в сell конфигурационном файле.

Jailhouse — это открытый проект, который можно найти на https://github.com/siemens/jailhouse .

Демо

Процессор Linux SDK предоставляет для Jailhouse готовые бинарные файлы. Вы можете попробовать запустить их сразу после установки. В этом разделе предполагается, что вы уже установили PLSDK и загрузили Linux на AM572X-EVM или AM572x-IDK.
Примечание: чтобы использовать гипервизор jailjouse:

  1. Установите переменную среды u-boot bootargs: setenv bootargs vmalloc=512M
  2. Используйте am572x-evm-jailhouse.dtb для AM572x-EVM или am572x-idk-jailhouse.dtb для AM572x-IDK

Компоненты с предварительной сборкой:

Как уже упоминалось в предыдущем разделе, Jailhouse состоит из следующих компонентов, которые предварительно созданы и скопированы в целевую файловую систему:

  1. jailhouse.ko kernel модуль расположен по следующему пути /lib/modules/4.9.28-<gitid>/extra/driver;
  2. jailhouse.bin — гипервизор расположен в директории /lib/firmware;
  3. Jailhouse инструмены управления jailhouse расположены по следующему пути /usr/local/libexec/jailhouse and /usr/sbin;

Чтобы создать корневую cell и inmate cell, нам необходимо предоставить файлы конфигурации cell. Эти файлы конфигурации и бинарные файлы примеров находятся в каталоге /usr/share/jailhouse/examples:

root@am57xx-evm:/usr/share/jailhouse/examples# ls -1 
am572x-rtos-icss.cell
am572x-rtos-pruss.cell
am57xx-evm-ti-app.cell
am57xx-evm.cell
am57xx-pdk-leddiag.cell
icss_emac.bin
led_test.bin
linux-loader.bin
pruss.bin
ti-app.bin

где

  • am57xx-evm.cell — файл конфигурации корневой cell;
  • ti-app.bin и am57xx-evm-ti-app.cell — bare metal (firmware) inmate и его cell конфигурация;
  • led_test.bin и am57xx-pdk-leddiag.cell — пример для inmate PDK led_test и его конфигурация cell (led_test.bin может работать только на AM572x-EVM);
  • pruss.bin и am572x-rtos-pruss.cell — примеры inmate TI-RTOS PRUSS и конфигурация его cell (pruss.bin может работать только на AM572x-IDK);
  • icss_emac.bin и am572x-rtos-icss.cell — пример inmate ICSS-EMAC TI-RTOS и конфигурация его cell (icss_emac.bin может работать только на AM572x-IDK);
  • linux-loader.bin — загрузчик, необходимый для запуска inmates, начальный адрес которого не равен 0x0;

Запуск демо на AM572x-EVM
Запуск bare-metal ti-app.bin
Вот шаги для запуска демо:

  • Загрузите Linux
  • Вставить модуль ядра jailhouse.ko
root@am57xx-evm:~# modprobe jailhouse
  • Включите гипервизор используя am57xx-evm.cell корневой cell конфигурационный файл
root@am57xx-evm:~# jailhouse enable /usr/share/jailhouse/examples/am57xx-evm.cell 
Initializing Jailhouse hypervisor v0.6 on CPU 1
Code location: 0xf0000030
Page pool usage after early setup: mem 30/4073, remap 32/131072
Initializing processors:
 CPU 1... OK
 CPU 0... OK
Page pool usage after late setup: mem 39/4073, remap 38/131072
Activating hypervisor
[ 4155.880217] The Jailhouse is opening.
  • Создайте cell для inmate
root@am57xx-evm:~# jailhouse cell create /usr/share/jailhouse/examples/am57xx-evm-ti-app.cell 
[ 5270.449687] CPU1: shutdown
[ 5270.453221] NOHZ: local_softirq_pending 20
Created cell "AM57XX-EVM-timer8-demo"
Page pool usage after cell creation: mem 51/4073, remap 38/131072
[ 5270.487970] Created Jailhouse cell "AM57XX-EVM-timer8-demo"
  • Загрузите ti-app.bin inmate бинарь.
root@am57xx-evm:~# jailhouse cell load 1 /usr/share/jailhouse/examples/ti-app.bin 
Cell "AM57XX-EVM-timer8-demo" can be loaded
  • Старт бинаря.
root@am57xx-evm:~# jailhouse cell start 1 
Hey, I'm working !!!!!!!!!!!
timer id 4fff2b01
timer value fffffc17; irq status 00000002; raw 00000002
min 00000017; avr 0000001b; max 000002c1
min 00000017; avr 0000001b; max 000000f3
min 00000017; avr 0000001b; max 000002c8
min 00000017; avr 0000001b; max 00000148
min 00000017; avr 0000001b; max 000002d4
min 00000017; avr 0000001b; max 00000158

ПРИМЕЧАНИЕ: все компоненты: корневая cell, гипервизор и демо inmate используют один и тот же UART, и за этого конфликт. Как только inmate начал использовать UART, Linux перестает получать какие-либо данные с консоли. Чтобы обойти это и продолжить управление гипервизором, вы можете подключиться к EVM и отправить все команды из telnet-оболочки (можно использовать ssh). Гипервизор все еще будет использовать консоль Linux для печати отладочных сообщений.

  • Остановка бинаря.
root@am57xx-evm:~# jailhouse cell shutdown 1

ПРИМЕЧАНИЕ. Вы можете восстановить консоль Linux, убив процесс «/bin/login» из сеанса telnet.

  • Уничтожить cell
root@am57xx-evm:~# jailhouse cell destroy 1                                                                                                       
Closing cell "AM57XX-EVM-timer8-demo"
Page pool usage after cell destruction: mem 39/4073, remap 38/131072
[ 6201.111168] Destroyed Jailhouse cell "AM57XX-EVM-timer8-demo"
  • Отменить (остановить) гипревизор
root@am57xx-evm:~# jailhouse disable                                                                                                              
Shutting down hypervisor
 Releasing CPU 0
 Releasing CPU 1
[ 6248.149728] The Jailhouse was closed.

Примечание:

Вы можете выключить и запустить один и тот же бинарный файл несколько раз. Каждый раз, когда вы запускаете бинарный файл, он стартует с самого начала. Если у вас есть разные бинарные файлы, которые используют одни и те же ресурсы cell, вы можете использовать созданную cell для их запуска. Вам нужно просто закрыть cell, загрузить другой бинарный файл и запустить его. Если вам нужно запускать различные двоичные файлы, требующие разных ресурсов, вам нужно закрыть текущую ячейку, уничтожить ее, создать новую с необходимыми ресурсами, загрузить новый бинарный файл и запустить его.

Запуск PDK led_test.bin примера
После включения гипервизора, создаем pdk cell.

root@am57xx-evm:~# jailhouse cell create /usr/share/jailhouse/examples/am57xx-pdk-leddiag.cell 
[  312.419978] CPU1: shutdown
Created cell "AM57XX-EVM-PDK-LED"
Page pool usage after cell creation: mem 54/4075, remap 38/131072
[  312.470723] Created Jailhouse cell "AM57XX-EVM-PDK-LED"
root@am57xx-evm:~#

Загружаем led_test.bin

root@am57xx-evm:~# jailhouse cell load 1 /usr/share/jailhouse/examples/led_test.bin 
Cell "AM57XX-EVM-PDK-LED" can be loaded

и запускаем его.

root@am57xx-evm:~# jailhouse cell start 1
Started cell "AM57XX-EVM-PDK-LED"
root@am57xx-e
*********************************************
*                 LED Test                  *
*********************************************

Testing LED
Blinking LEDs...
Press 'y' to verify pass, 'r' to blink again,
or any other character to indicate failure: r

Blinking again
Press 'y' to verify pass, 'r' to blink again,
or any other character to indicate failure: y
Received: y

Test PASSED!

Вы можете увидеть мигающие светодиоды, нажмите кнопку «r», чтобы повторить тест.

Примечание: этот пример просто демонстрирует способность гипервизора запускать бинарные файлы, которые были собраны вне дерева исходного кода jailhouse. Этот и другие примеры RTOS были размещены для этой цели. Описание функций примеров см. в документации по RTOS SDK.

Запуск демо проекта на AM572x-IDK

Два примера приложений TI-RTOS были портированы для гипервизора Jailhouse: pruss.bin и icss_emac.bin. В отличие от led_test.bin, который имеет свой собственный код запуска, скрипт компоновщика и был связан с адресом запуска 0x0, pruss.bin и icss_emac.bin используют ti-rtos инфраструктуру сборки как можно больше. Поэтому они связаны с адресным пространством DDR EVM’s (начиная с 0x80000000), и их точка входа не 0x0. Для поддержки загрузки и запуска такого приложения используется специальная командная оболочка.

Чтобы запустить pruss.bin приложение, включите гипервизор так же, как и для других примеров.

cd /usr/share/jailhouse/examples/
root@am57xx-evm:/usr/share/jailhouse/examples# modprobe jailhouse
root@am57xx-evm:/usr/share/jailhouse/examples# jailhouse enable ./am57xx-evm.cell

Initializing Jailhouse hypervisor  on CPU 0
Code location: 0xf0000030
Page pool usage after early setup: mem 30/4075, remap 32/131072
Initializing processors:
 CPU 0... OK
 CPU 1... OK
Page pool usage after late setup: mem 39/4075, remap 38/131072
Activating hypervisor
[  710.008555] The Jailhouse is opening.

Создайте cell pruss.bin

root@am57xx-evm:/usr/share/jailhouse/examples# jailhouse cell create ./am572x-rtos-pruss.cell                                                                                  
[  745.067783] CPU1: shutdown
Created cell "AM572X-IDK-PRUSS"
Page pool usage after cell creation: mem 54/4075, remap 38/131072
[  745.107324] Created Jailhouse cell "AM572X-IDK-PRUSS"
root@am57xx-evm:/usr/share/jailhouse/examples#

Используйте команду загрузки ячеек для загрузки нескольких необходимых компонентов:

root@am57xx-evm:/usr/share/jailhouse/examples# jailhouse cell load 1 linux-loader.bin -a 0 -s "kernel=0x80005128" -a 0x100 pruss.bin -a 0x80000000
Cell "AM572X-IDK-PRUSS" can be loaded

где

  • linux-loader.bin — это небольшое приложение, предоставляемое и построенное деревом исходников jailhouse. Как видите приложение (- a 0) загружается в виртуальный адрес 0x0
  • «- s «kernel=0x80005128″ — a 0x100 » — это аргумент linux_loader, загруженный в виде строки в виртуальный адрес 0x100, который указывает linux-loader на ветку pruss.bin точка входа  0x80005128
  • pruss.bin, загружается в виртуальный адрес 0x80000000 — адрес, с которым связано данное приложение
  • После загрузки запустите inmate, как обычно:
root@am57xx-evm:/usr/share/jailhouse/examples# jailhouse cell start 1
Started cell "AM572X-IDK-PRUSS"
root@am57xx-evm:/usr/share/jailhouse/examples# passed verify constant tbl entry for instance 1: pruNum: 0
eventwait: waiting for the INTC event from PRU
sending the INTC event to the PRU for instance: 1 , pru num: 0
eventwait: got the INTC event from PRU, count: 1
eventwait: waiting for the INTC event from PRU
sending the INTC event to the PRU for instance: 1 , pru num: 0
eventwait: got the INTC event from PRU, count: 2
eventwait: waiting for the INTC event from PRU
sending the INTC event to the PRU for instance: 1 , pru num: 0
eventwait: got the INTC event from PRU, count: 3
eventwait: waiting for the INTC event from PRU
sending the INTC event to the PRU for instance: 1 , pru num: 0
eventwait: got the INTC event from PRU, count: 4
eventwait: waiting for the INTC event from PRU
sending the INTC event to the PRU for instance: 1 , pru num: 0
eventwait: got the INTC event from PRU, count: 5
eventwait: waiting for the INTC event from PRU
Testing for instance: 1, pru num: 0 is complete
passed verify constant tbl entry for instance 1: pruNum: 1                                               
sending the INTC event to the PRU for instance: 1 , pru num: 1                                           
eventwait: got the INTC event from PRU, count: 1                                                         
eventwait: waiting for the INTC event from PRU                                                           
sending the INTC event to the PRU for instance: 1 , pru num: 1
eventwait: got the INTC event from PRU, count: 2
eventwait: waiting for the INTC event from PRU
sending the INTC event to the PRU for instance: 1 , pru num: 1
eventwait: got the INTC event from PRU, count: 3
eventwait: waiting for the INTC event from PRU
sending the INTC event to the PRU for instance: 1 , pru num: 1
eventwait: got the INTC event from PRU, count: 4
eventwait: waiting for the INTC event from PRU
sending the INTC event to the PRU for instance: 1 , pru num: 1
eventwait: got the INTC event from PRU, count: 5
Testing for instance: 1, pru num: 1 is complete
passed verify constant tbl entry for instance 2: pruNum: 0
eventwait2: waiting for the INTC event from PRU
sending the INTC event to the PRU for instance: 2 , pru num: 0
eventwait2: got the INTC event from PRU, count: 1
eventwait2: waiting for the INTC event from PRU
sending the INTC event to the PRU for instance: 2 , pru num: 0
eventwait2: got the INTC event from PRU, count: 2
eventwait2: waiting for the INTC event from PRU
sending the INTC event to the PRU for instance: 2 , pru num: 0
eventwait2: got the INTC event from PRU, count: 3
eventwait2: waiting for the INTC event from PRU
sending the INTC event to the PRU for instance: 2 , pru num: 0
eventwait2: got the INTC event from PRU, count: 4
eventwait2: waiting for the INTC event from PRU
sending the INTC event to the PRU for instance: 2 , pru num: 0
eventwait2: got the INTC event from PRU, count: 5
eventwait2: waiting for the INTC event from PRU
Testing for instance: 2, pru num: 0 is complete
passed verify constant tbl entry for instance 2: pruNum: 1
sending the INTC event to the PRU for instance: 2 , pru num: 1
eventwait2: got the INTC event from PRU, count: 1
eventwait2: waiting for the INTC event from PRU
sending the INTC event to the PRU for instance: 2 , pru num: 1
eventwait2: got the INTC event from PRU, count: 2
eventwait2: waiting for the INTC event from PRU
sending the INTC event to the PRU for instance: 2 , pru num: 1
eventwait2: got the INTC event from PRU, count: 3
eventwait2: waiting for the INTC event from PRU
sending the INTC event to the PRU for instance: 2 , pru num: 1
eventwait2: got the INTC event from PRU, count: 4
eventwait2: waiting for the INTC event from PRU
sending the INTC event to the PRU for instance: 2 , pru num: 1
eventwait2: got the INTC event from PRU, count: 5
Testing for instance: 2, pru num: 1 is complete
All tests have passed

Вы можете запустить icss_emac.bin аналогичным образом, используя соответствующую конфигурацию ячейки. Обратите внимание, что icss_emac имеет другую точку входа — 0x80000000.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Лимит времени истёк. Пожалуйста, перезагрузите CAPTCHA.