Особливості віртуалізації Xen в автомобільній сфері

Я Lead Software Engineer, займаюся проектами по віртуалізації для автомотів-сектора в GlobalLogic. Ця стаття підготовлена на основі мого виступу на Root Linux Conference 2017 , і є продовженням теми, яку недавно розкрив Ларс Курт .

Протягом останніх 5 років GlobalLogic активно займається проектами в автомобільній сфері. Деякі з них — спочатку комерційні, деякі — експериментальні прототипи (proof of concept або просто PoC), частина з яких згодом перейшла на комерційну основу. Одне з найбільш цікавих і важливих для нас напрямків у цій сфері — це технології віртуалізації. У цій статті я розповім про те, навіщо вони потрібні і як працюють, а також торкнуся основні проблеми, з якими ми зіткнулися в процесі розробки, а також способи їх вирішення.

Почнемо з того, чому технології віртуалізації зараз особливо актуальні для автомобільної індустрії. У будь-якому сучасному автомобілі середнього рівня (не кажучи вже про машини преміум-класу) використовується 2-3 різних комп'ютера.

Один з них відповідає за роботу інформаційно-розважальної системи автомобіля (радіо, відтворення музики, навігація — все те, що ми звикли бачити в своєму смартфоні). Як правило, ця система працює на базі Android, але можуть бути виключення, наприклад, Tizen .

Інший комп'ютер у звичайному житті водій взаємодіє з ним рідко) відповідає за систему запалювання, сервіси екстреного оповіщення при аварії і т. п. Цей комп'ютер працює під управлінням операційної системи реального часу (real-time OS, RTOS), як правило, закритою та/або пропрієтарної (втім, бувають і винятки, наприклад, FreeRTOS або QNX). Головні вимоги до такої системи — стабільність, надійність і чуйність, оскільки це пристрій обслуговує запити, час виконання яких дуже обмежена і дуже критично.

Також в автомобілях преміум-класу окремий комп'ютер відповідає за роботу кластера (приладова панель над кермом автомобіля). Як правило, такий комп'ютер працює під управлінням якоїсь вузькоспеціалізованої Linux-системи з композитним менеджером Weston. Головна вимога до такої системи — швидкий високоякісний рендеринг зображення. В іншому випадку показання спідометра або тахометра будуть відображатися на панелі з затримкою, що зробить їх непотрібними для водія.

Один за всіх

Тепер розглянемо типову автомобільну платформу. Як правило, це дуже продуктивна система: 8-ядерний процесор: чотири А57, чотири А53, висококласний GPU PowerVR від Imagination, 4 Гб оперативної пам'яті, величезна різноманітність різних шин. Для вирішення кожного конкретного набору задач — будь-то кластер або інформаційно-розважальні системи — її можливості явно надлишкові. Тому ми вирішили, що можна поєднати кілька фізичних комп'ютерів в одному за рахунок використання віртуалізації. Які переваги ми отримуємо від такого використання?

По-перше, це безпека і стійкість до відмов. Це найважливіші переваги, з точки зору автомобільної промисловості, особливо з урахуванням почастішали спроб злому сучасних авто (в першу чергу це стосується самокерованих автомобілів, хоча і не тільки).

По-друге, це зменшення вартості апаратної платформи. Як не крути, один, навіть дуже продуктивний автомобільний комп'ютер, буде коштувати дешевше посередніх двох-трьох.

По-третє, економія грошей і часу відбувається на етапі підтримки та оновлення програмного забезпечення всієї системи. Справа в тому, що у випадку з віртуалізацією ми можемо модернізувати та оновити систему не цілком, а окремими частинами. Наприклад, після виходу Android Z ми можемо досить швидко перенести його в нашу інформаційно-розважальну систему. При цьому таке оновлення ніяк не вплине на роботу кластера або інших систем. Якщо ж віртуалізації у нас немає, то, оновлюючи інформаційно-розважальну систему, ми будемо змушені оновлювати та інші системи, що, ймовірно, потягне за собою питання сертифікації, безпеки і т. п. У свою чергу, це не тільки ускладнює процес оновлення і вимагає більшої кваліфікації розробників), але і розтягує його на тривалий час.

Зворотна сторона віртуалізації — система стає значно більш складною, так як ми додаємо додатковий рівень абстракції над звичайної операційної системою. Крім того, ми повинні забезпечувати коректне взаємодія між декількома операційними системами, враховувати питання безпеки і стабільності. Все це, зрозуміло, впливає на вартість розробки — на її створення потрібно більше часу більш досвідчених фахівців, але ми переконані, що в кінцевому рахунку все це окупається описаними вище перевагами.

Чому Xen?

По-перше, Xen — це гіпервізор так званого першого типу (type 1), що дозволяє його використовувати на «голе залізо» і стартувати практично будь-яку операційну систему в якості гостьової. Вже, як кажуть, «з коробки» Xen підтримує багато гостьових операційних систем: Windows, Linux, FreeBSD, QNX і ще багато чого іншого, нехай навіть з деякими обмеженнями.

По-друге, це проект з відкритим вихідним кодом, який підтримується сильним і активним спільнотою розробників. Проект активно розвивається, тому постійно закриваються уразливості, додається нова функціональність, регулярно виходять нові стабільні версії системи. Вже спочатку Xen відповідає досить суворим вимогам з безпеки і надійності, що доведено досвідом використання його такими серйозними компаніями, як Amazon, BitDefender та ін.

По-третє, починаючи з версії 4.4, в Xen з'явилася підтримка архітектури ARM, що називається, «з коробки». Нам не доводиться щоразу додавати окрему підтримку, оскільки вона стабільна, надійна і після тестування.

По-четверте, універсальність цієї системи в загальному випадку зав'язана тільки на потужності платформи. Ми можемо одночасно запускати до 4 тисяч операційних систем, якщо у нас дозволяють можливості обладнання.

І нарешті, по-п'яте, у Xen відносно невелика кодова база, що дозволяє трохи знизити поріг входження, плюс легше шукати можливі проблеми в певних частинах проекту. Невелика кодова база, до речі, також позитивно впливає на безпеку системи, тому що важче провести якісь коміти, які приведуть до порушення безпеки.

Як це працює?

Отже, у нас є декілька операційних систем, які управляються з так званого Dom0. Це привілейований домен, який може керувати апаратною платформою майже без обмежень. В основному він відповідає за створення гостьових операційних систем, за їх модифікацію і видалення. Також дуже ефективно, щоб у Dom0 «біг» Watchdog, який підтримується Xen через спеціальний механізм. Так, якщо впаде з гостьових доменів, Watchdog його легко підніме без впливу на роботу інших систем.

Якщо в реальності відбудеться якийсь збій і в автомобілі впаде система, відповідальна за роботу тахометра, нічого страшного не станеться. Це ніяк не вплине на роботу, наприклад, спідометра або системи запалювання. Комусь, можливо, це доставить тимчасові незручності, але в цілому на стабільність роботи і безпеку їзди це не вплине.

Крім того, в Dom0, як правило, працюють драйвери фізичних пристроїв. Це такий спеціальний тип драйверів, який дозволяє використовувати їх одночасно декількома операційними системами з допомогою паравиртуализированного підходу. Суть цього підходу в тому, що ми надаємо інтерфейс (через спеціально написані драйвера-прошарку) для використання фізичних пристроїв гостьовим операційним системам (так звані DomU), наприклад, для відтворення звуку або виводу зображення на екран. При цьому в реальності всі драйвери цих пристроїв знаходяться в іншому домені — Dom0.

Подальший розвиток цього підходу — дезагрегація драйверів. Зокрема, для розробки рішень для автомобільної індустрії ми виділили окремий драйвер-домен, який містить в собі основні «залізні» драйвера. Dom0 в даному випадку підхоплює тільки невеликий набір драйверів, необхідних для старту і для управління іншими доменами. Наприклад, якщо який-небудь драйвер падає, то драйвер-домен теж падає, але Dom0 відстежує цю подію і автоматично перезапускає драйвер-домен.

Проблеми і рішення

Раніше вже згадувалося, що в Xen є підтримка архітектури ARM. Що потрібно, щоб операційна система «бігла» на основі гіпервізора на ARM? На ARM операційна система «біжить» в режимі EL2 на AArch64, а гостьові домени у нас в EL1-режимі. Основна проблема для автомотива і не тільки — це проблема перекладу бутлоадера перед стартом гіпервізора в потрібний режим.

В загальному випадку для вирішення цієї проблеми використовується U-boot. Але це далеко не обов'язково, є досить багато винятків. Плюс іноді цей переклад не є загальнодоступним, оскільки іноді це досить проприетарная інформація. Але тим не менш U-boot з 2016 року підтримує автоматичний переклад ARM архітектур в Virtualization mode. Тобто ми стрибаємо на саме ядро, в даному випадку на гіпервізор вже в Virtualization mode. Тому основною проблемою є відсутність стандартизованого підходу в загальному випадку і деяка закритість інфраструктури, особливо якщо ми говоримо про закритих архітектурі, наприклад, Qualcomm.

Пам'ять

Ще одна досить складне і комплексне завдання — це пам'ять. Давайте розглянемо варіант з трехдоменной конфігурацією. Як працює пам'ять в Xen в загальному випадку? У нас є поняття фізичної і машинного адреси. Фізичний — це той адреса, який ми бачимо з боку домену. Ну, домен думає, що він біжить по фізичним адресами. Насправді в термінології Xen він «біжить» через проміжні адреси за машинним адресами. Вони в кращому випадку можуть не відповідати тим адресами, за якими будуть бігти гостьові домени або Dom0 за вкрай рідкісним винятком.

Розташування доменів пам'яті за замовчуванням в трехдоменной конфігурації

Dom0 спеціально налаштований і працює таким чином, що його внутрішнє подання адрес і машинне подання адрес, з якими він взаємодіє, однакове. Навіщо це нам треба? Проблема в тому, що в Dom0 знаходяться всі фізичні драйвери. Як мінімум одна з проблем — це проблема з DMA.

Коли ми створюємо DMA-транзакцію, то повинні працювати з машинним адресами в термінології Xen (тобто налаштувати буфера на ці адреси, але це не завжди можливо, так як для гостьових операційних систем машинні та фізичні адреси будуть різними). Є кілька способів зробити це так, щоб самі гостьові операційні системи знали про це і використовували той факт, що у них фізичні адреси не відповідають машинним. Один з них, дуже брудний хак — це правка стартового початкового адреси пам'яті, за якою «біжить» конкретна операційна система. Це так звана RAM base.

Подправленное розміщення DomainD в пам'яті (пам'ять нарізана одним цільним шматком) — DomainD rambase підправлений для отримання 1:1 замапленного домену

За замовчуванням Xen створює RAM base починаючи з 0?80000000, але це можна змінити. І по факту це більше механічна робота, тому що це не можна зробити в один прохід. Вам треба правити в декількох місцях, починаючи з конфігурації конкретного домену, закінчуючи кінцевим device tree. Але тим не менш це має право на життя — на схемі можна побачити, що Xen виділив пам'ять драйвера для домену з 0xB0000000 — 0xBFFFFFFF, але сама операційна система драйвер-домену думала, що вона біжить за адресами починаючи з 0?80000000. Однак ми поправили стартовий адресу, і тепер у нас домен один в один замаплен.

Але за фактом залишається ще один недолік цього методу — ми можемо аллоцировать тільки послідовні шматки пам'яті: нехай різного розміру, але послідовні, що загалом зменшує універсальність підходу і його гнучкість.

Пам'ять для DomainD набирається автоматично з декількох шматків, кожен з яких 1:1 замаплен

Другим підходом є набір пам'яті по частинах. Xen спочатку оперує досить великими шматками пам'яті, і не завжди їх можна «нарізати» таким механізмом. Нам, наприклад, треба 766 МБ драйвер-домені. Якщо не помиляюся, найближче ціле значення пам'яті, яке ми можемо виділити одним шматком, — 1 ГБ, після цього буде вже дрібними шматочками по 2MB. Нам ніхто не заважає, у принципі, ці шматочки натягать з різних частин оперативної пам'яті і зробити так, щоб кожен з них був один в один «замаплен». Це нам дозволить перекласти роботу по трансляції адрес на ядро. Так, добре, що у нас будуть якісь дірки, у нас буде і безперервний шматок, але вся трансляція проходить на стороні Linux. На даний момент це найбільш ефективний підхід, який ми використовуємо.

Найбільш правильним і ефективним методом вирішення проблеми з DMA буде використання SMMU (IOMMU) (SMMU — system mmu, IOMMU — input/output mmu) — в цьому випадку трансляція адрес буде виконуватися на апаратному рівні, прозоро для пристрою. Але, на жаль, його наявність у SoC залежить від виробника (та наявності підтримки цього пристрою в BSP для даного SoC). А також підтримки з боку Xen — але спільнота працює над цим рішенням.

Графіка і прошивки

Наступна проблема, з якою можна зіткнутися, — це проблема з прошивками. Наприклад, у нас є якийсь DSP-процесор (вузькоспеціалізований процесор, призначений для вирішення задач цифрової обробки сигналів), який обробляє відео і, як правило, використовує резерв пам'яті device tree для ARM. У загальному випадку доступ до цих прошивка є тільки у виробників пристроїв. І проблема в тому, що нам треба отримати доступ до функціональності цих прошивок, не дивлячись на те, що процесор використовує резерв. На жаль, ця проблема складно вирішувана. Одне з банальних рішень, до якого доводилося вдаватися, — це бінарний патч в runtime. Ми знаємо, за якими адресами у нас біжить домен, і ми в runtime просто патчим адреси, на які налаштована прошивка для DSP. Це дуже брудний хак, але тим не менше іноді він має право на життя.

Інший підхід, який в принципі зараз неможливий в силу специфічних вимог деяких замовників і виробників, — це відмова від використання якогось програмного забезпечення або пристроїв периферії в гостьових доменах. При цьому, зрозуміло, ми хочемо якимось чином взаємодіяти, наприклад, з GPU. Готового рішення цієї задачі немає, але найбільш правильним і ефективним методом, як вказувалося раніше, буде використання SMMU.

По своїй складності топові GPU (наприклад, A72 Mali) вже перевершують звичні обчислювальні процесори. Це створює розробникам додаткові проблеми — складність самого графічного «заліза», жорсткі пропрієтарні ліцензії, проблеми з документацією, яку дуже непросто отримати від виробника.

Також на даний момент в 99% GPU відсутня підтримка апаратної віртуалізації, тому доводиться шукати якісь окремі варіанти і механізми для вирішення цих завдань.

Один із способів використання GPU віртуальними операційними системами, який ми реалізували, — це програмний context switch. На кожен switch домену ми зберігаємо стан і набір регістрів GPU і відновлюємо з іншого домену. Тобто процес повторюється: зберегли відновили; зберегли-відновили. Цей механізм досить простий у створенні, але проблема, як мінімум, в тому, що GPU досить складний пристрій, і всі ці операції — не миттєві.

Чим більше регістрів ми зберігаємо, тим більше часу ми втрачаємо в процесі context switch. Тому треба зберігати мінімальний набір регістрів. Плюс для такого підходу характерно включення/вимикання GPU. На кожному етапі ми повинні його вимикати/включати, що в термінах заліза не є швидким процесом. Нам треба чекати якихось бітів в регістрах, чекати значення в пам'яті та інше.

Другим, більш ефективним підходом є використання полуаппаратной віртуалізації. Це віртуалізація з підтримкою з боку GPU. В такому разі ми перекладаємо частину роботи на залізо, яке дозволяє нам зберігати стан графічного процесора. Однак це вимагає дуже великих витрат на підтримку з боку віртуалізації в драйверах. Це реалізовано в деяких драйвери з допомогою виробника, що дозволяє спростити і більш коректно це зробити. Справа в тому, що будь-яка підтримка віртуалізації в принципі не залежна від гіпервізора, на якому ми «біжимо».

Якщо говорити про продуктивність рішень, то перше рішення, звичайно, менш продуктивно, тому що ми повинні все це прогнати через CPU, що досить довго. Так, втрата продуктивності в першій платформі становить близько 5-10%. На другій платформі — всього 3% в трехдоменной конфігурації. Найбільш правильним є використання повної графічної підтримки віртуалізації. Але, наскільки нам відомо, це існує буквально в декількох чіпах, і в автомотиве вони поки не використовуються, але може знайдуть своє застосування вже через пару років.

PV-драйвера

Як вже говорилося раніше, PV-драйвера — це якийсь спеціальний підхід до розподілу можливостей реального заліза між декількома доменами. У нас є якийсь backend, який взаємодіє з апаратним програмним забезпеченням через цей драйвер в Linux і якийсь frontend, який надає не обов'язково повний доступ до всієї функціональності.

Таким чином, ми, наприклад, можемо програвати звук з декількох доменів через одне фізичне пристрій. Можемо коректно мікшувати звук з різних доменів, заглушити якийсь окремий домен і т. п.

Спочатку «з коробки» були доступні тільки основні драйвери — PV-блок, який використовується для віртуалізації блокових пристроїв. Паравиртуальные драйвери для мережі і PCI, SCSI і Frame buffer, а також USB (pvUSB) були доступні тільки на архітектурі x86. PvUSB було спочатку доступно і в більш старих версіях, але продуктивність була дуже низькою, як і переносимість, але ось 4.7 додали базову підтримку pvUSB. Однак коммюніті продовжує розробляти інші PV-драйвера.

На жаль, цього все ще недостатньо. Адже використовуючи інформаційно-розважальну систему автомобіля, ми хочемо в першу чергу дивитися відео, фотографії і слухати музику. Значить, нам потрібні як мінімум популярні кодеки. Крім того, для управління системою в автомобілі ми навряд чи будемо використовувати мишку або клавіатуру, а, значить, нам також потрібна підтримка сенсорного екрану і т. п. Всього цього в готовому вигляді немає, тому нам довелося створювати всі необхідні компоненти з нуля.

Деякі з таких інтерфейсів вже увійшли або скоро увійдуть у мейнлайн. Їх, можливо, будуть використовувати частково «з коробки», а в подальшому вони будуть включені в ядро системи.

Тренди та перспективи

Одне з найбільш цікавих для автомотива напрямів — це операційні системи реального часу. Як я вже говорив, робота деяких бортових вбудованих комп'ютерів критична з точки зору часу, вони важливі для того, щоб оповістити про певні події, щоб захистити людину. Xen має деякі механізми підтримки RTOS, але, на жаль, вони ще не дуже розвинені.

За замовчуванням Xen використовує scheduler, який weight-based, тобто розрахований на роботу з вагами. Він не гарантує чуйність операційної системи. Є також механізм RTDS scheduler, який надає м'яке реальний час, але він на даний момент в розробці. Цікавий для автомотива ARINC653 scheduler: він дозволяє надати жорстке реальний час, але не має підтримки багатоядерності. В подальшому, можливо, це буде виправлено, можливо, немає.

Також на сьогоднішній день досить цікавим трендом, як я вже говорив, є дезагрегація — використання окремого драйвер-домену. Чому б нам в якості Dom0 не використовувати якусь тонку операційну систему реального часу, FreeRTOS, наприклад? Це дозволить нам більш ефективно взаємодіяти з залізом, відслідковувати його стан, підтримувати стан системи в цілому.

Однак на даний момент повноцінної підтримки в Dom0 немає. Є підтримка з боку MiniOs, але поки що це не зовсім чесна підтримка. Це запуск декількох операційних систем з Xen в момент його старту. Тобто це не дає нам підтримки libxl-стека. Якщо ми захочемо вручну створювати домени, то нам знадобляться інші механізми.

Також нами була розроблена часткова підтримка QNX в якості гостьового домену DomU. Це дозволило нам скористатися його перевагами для подальшої сертифікації. Крім того, в якості Dom0 можна використовувати Linux з реал-тайм патчами. Але він, звичайно, не надасть механізм жорсткого реального часу. Цього буде недостатньо для якихось критичних за часом виконання завдань.

В цілому можна сказати, що віртуалізація для автомобільної промисловості — досить складна область, і тут вистачає завдань, для яких поки ще немає готових рішень. Але саме тому це дуже цікава тема для всіх, хто хоче спробувати себе в R&D і зайнятися створенням рішень, які, можливо, стануть стандартом для цілої індустрії. У будь-якому випадку це дуже перспективний напрям. Якщо воно цікаво і вам — приєднуйтесь. Більше про Xen і все, що з ним пов'язано, ви можете дізнатися на сторінці wiki.xen.org/wiki/Main_Page

Опубліковано: 11/08/17 @ 07:21
Розділ Різне

Рекомендуємо:

DOU Books: 5 книг, які радить Всеволод Демкин
DOU Ревізор в Depositphotos: «Фабрика фотографії з величезними open space»
Огляд ІТ-ринку праці: Хмельницький
Ruby/Rails дайджест #8: реліз Active Storage, масштабується RoR чи все-таки ні, курси з вивчення Ruby/Rails
VR/AR – 5 вирішальних факторів розвитку технології