Придумываем название для нового гипервайзера для архитектуры MIPS с аппаратно-поддерживаемой виртуализацией

    На днях в офисе Imagination Technologies в Санта-Клара, Калифорния ко мне подходит специалист по многоядерному Линуксу Леонид Егошин и говорит:

    Егошин: Вот, написал самый маленький гипервайзер в мире.

    Я: Да? А как называется?

    Егошин: Еще не придумал. И маркетинг названия не спустил. Придумай название! Это все равно будет opensource-проект.

    Я: Мне чего-то трудно такое придумать. Как говорится «как вы яхту назовете, так она и поплывет». Надо общественность спросить.

    Егошин: И я еще в апреле в Долгопрудном буду, в МФТИ. Не был там с XX века. Есть ли там кто-нибудь, кого интересует MIPS-Linux/IoT/гипервизоры на MIPS?

    Я: Ну об этом тоже можно спросить общественность.

    Итого, я написал этот пост, чтобы спросить общественность. Но сначала я расскажу, кто такой Леонид Егошин и что такое гипервайзер.

    ***

    Не вся молодежь знает, но в СССР был свой Unix. Не при Брежневе, но уже при Андропове.

    И вот одним из первых советских юниксологов и был Егошин (он единственный на фотке на Красной Площади 1980-х, кто улыбается). Потом Егошин переехал в Silicon Valley и стал работать в MIPS Technologies, которая стала Imagination Technologies. На снимке справа Егошин уже в 2015 году, с первой привезенной в Америку из России платой с российским микропроцессором Байкал-Т — Егошин помогал отлаживать на ней Линукс:



    А теперь что такое гипервайзер.

    Гипервайзер — это такая программа, которая управляет работой двух или более операционных систем, которые выполняются на процессоре одновременно внутри виртуальных машин. Софтверу внутри виртуальной машины кажется, что ему принадлежит вся реальная машина, все ее порты ввода/вывода, память и прерывания.

    Виртуализация — это следующий шаг после kernel / user mode (режима ядра / пользовательского режима). В kernel/user парадигме операционная система защищает себя от пользовательских программ и пользовательские программы друг от друга. Привилегированный режим ядра включается, когда во время выполнения пользовательской программы происходит прерывание. Тогда ОС смотрит, что произошло, и может переключится на выполнение другой пользовательской программы. В случае виртуализации поверх kernel/user включаются еще и режимы root/guest для защиты нескольких guest операционных систем друг от друга и разделения между ними ресурсов. Этим занимается гипервайзер в режиме root:

    https://www.imgtec.com/mips/architectures/virtualization/




    Виртуализацию не следует путать с виртуальной памятью. Виртуальная память может существовать и без виртуализации. В парадигме виртуальной памяти ОС/kernel управляет аппаратно-поддерживаемой таблицей трансляции виртуальных адресов, используемых пользовательскими программами, в физические адреса в памяти. Тем самым ОС создает иллюзию владения адресным пространством с одинаковыми виртуальными адресами у нескольких пользовательских программ, хотя физические адреса у них могут быть разные. В случае виртуализации у таблицы трансляции виртуальных адресов появляется следующий уровень, для создания иллюзий не только у пользовательских программ, но и у guest операционных систем.

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



    Вообще виртуализация как технология появилась более 40 лет назад, она была уже у IBM-овских мейнфреймов IBM/370 (но не IBM/360). В СССР виртуализация использовалась на ЕС ЭВМ, которые были аналогичны соответствующим IBM/370. Виртуализация была даже отражена в американской поп-культуре — некий стартап в художественной книжке времен первого интернет-бума 1990-х «Первые 20 миллионов долларов самые трудные» занимался в частности виртуализацией Apple Mac на сверхдешевых $300-долларовых PC (тогда это считалось фантастикой). Кстати, фильм, снятый по роману, оказался оказался одним из самых больших провалов в истории Голливуда, заработав всего $5,491 (пять тысяч с чем-то долларов) при потраченных $17 миллионах (см.)

    Но вернемся к Егошину. Гипервайзер Егошина работает на процессорном ядре MIPS M5150. Это экономичное ядро, которые используется для микроконтроллеров Microchip PIC32MZ и для чипов для интернета вещей.

    «О зачем на микроконтроллере виртуализация?!» — может воскликнуть читатель. Для секьюрити. Даже на небольшом чипе для IoT могут одновременно работать скажем встроенный Линукс и скажем очень защищенный код для работы с финансовыми транзакциями. Теперь если пользователь установит взломанную операционную систему, она не сможет получить доступ к другой ОС, выполняющей критические операции, потому что между двумя ОС стоит гипервайзер. Это становится особенно важно в случае интернета вещей, когда подброшенный в домашнюю сеть утюг или тостер может теоретически обмениваться информацией с главным компьютером хозяина.

    Егошинский гипервайзер может работать вот на такой плате Digilent chiKIT WI-FIRE:



    А теперь предоставим слово Леониду:

    Юра, основные сведения про hypervisor:

    Память — 35Kilobyte code, 24KB data

    Real-time values —

    1. Basic hypervisor call (HYPCALL): 74 clock cycles
    2. Force context switch to root and back: 336 clock cycles
    3. Emulation of guest access to a guarded device register: 207 clock cycles
    4. SW IRQ injection timing, no context switch: 173 clock cycles

    Общие устройства в совместном доступе, эмулируемые как собственные для каждого Guest:

    • PIC32MZ Interrupt controller в EIC моде.
    • Console UART.
    • Read-only регистры типа clock etc. Минимальный размер регистрового блока — 16байт.


    В настоящий момент поддержка только PIC32MZ(EF) модели, её Interrupt controller и устройства — плата, которую можно купить недорого.

    Конфигурация статическая, при помощи десктоп Python скриптов, которые делают пересчеты адресов расположения Guest-ов и их IRQ в таблицы для TLB (PTE) и управления прерываниями. В конце конфигурации все превращается в один .srec файл, который можно засунуть в PIC32MZ при помощи программы pic32prog от Вакуленко.

    UPD: Доплнительно, свежая ссылка на актуальность проблемы (вирус в банкоматах) — https://www.gazeta.ru/tech/2017/03/20/10584965/atm_virus.shtml#page2


    В общем если у вас есть хорошее название для гипервайзера или желание пересечься в МФТИ во время визита Леонида Егошина в альма-матер в апреле, вы можете либо ему писать на Leonid.Yegoshin@imgtec.com, либо оставлять здесь комментарии.

    ***

    Справка из Википедии про фото слева:

    Скрытый текст
    http://ru.wikipedia.org/wiki/%D0%94%D0%95%D0%9C%D0%9E%D0%A1

    Примерно в 1982—1983 годах копии операционной системы UNIX (v6 и v7) были привезены в Москву. На их основе в Институте атомной энергии им. И. В. Курчатова, при участии ряда специалистов других организаций, проводилось приспособление системы к местным условиям — локализация на русский язык и адаптация к отечественной технике, прежде всего — к машинам СМ-4 и СМ-1420. В то же время локализация проводилась в Институте повышения квалификации Минавтопрома, там новая система называлась «МНОС» (Машинно-Независимая Операционная Система). Позже две команды объединились, а система была переименована в «ДЕМОС» (Диалоговая Единая Мобильная Операционная Система). В 1985 году была выпущена версия 2.0 ОС Демос (с использованием исходных текстов BSD4.2). Проект закрыт в начале 1990-х.

    Разработчики ДЕМОС были награждены в 1988 году премией Совета министров СССР по науке и технике.

    Авторы Валерий Бардин, Сергей Аншуков, Вадим Антонов, Алексей Руднев, Сергей Рыжков, Николай Саух, Дмитрий Володин, Сергей Вакуленко, Михаил Коротаев, Павел Ходаков, Андрей «ache» Чернов, Михаил Паремский, Сергей Усиков, Леонид Егошин, Михаил Давидов, Михаил Флёров и др.


    Уважаемый читатель! Мне для статистики интересно:

    Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Комментарии 54
    • 0
      Ну собственно вопроса два — если это опенсорс — где на него можно посмотреть? И по поводу гипервизора — я правильно понял, что на питоне только скрипты конфигурирования, а сам гипервизор на более другом языке. Насколько он портабельный (на другие mips-платы)?
      • +1
        Написан он конечно на ассемблере и Си. По другим вопросам — ответит Егошин. Пока я видел код на его компьютере и презентацию от prpl foundation с будущей датой опубликования «23 марта 2017 года». Где гипервайзер находится в интернете я не знаю. Leonid.Yegoshin@imgtec.com
        • 0
          1) Конфигуратор на Python это конечно интересно, но ведь это же не node.js — почему нельзя было использовать что-то более приземленное?
          2) Уже известно под какой лицензией будет код?
          3) Поскольку решение как я понимаю должно быть кроссплатформенным — вы не думали сделать тулчейн на node.js или java или С++?
          • 0
            1) Что было под рукой — то и взял. Python есть везде.
            2) Или GPLv3 или что-то типа BSD, еще не очень думал.
            3) Нет, не думал. Там усложненные вычисления, так как на M5150 всего 16 регистров TLB и гипервизор использует переменный размер страниц для уменьшения page-faults. С Python-ом мне было проще написать преобразования.
        • +1
          Пока нет названия — нигде. Как будет имя — выложу на github.
          Да, на питоне только скрипты конфигурирования, сам гипервизор — С и ассемблер
          Основа привязана только к MIPS R5. Чуть-чуть надо будет доделать для P5600. Однако эмуляция контроллера прерываний сейчас сделана только для PIC32MZ(EF). То есть будет работать на любой плате с PIC32MZ(EF), например Digilent-овской.
          • 0
            А на R3000 не заведется даже в теории?

            P.S.: По названию — HIPS :)
            • +1
              Ух, это было бы круто!

              Коротко — нет конечно, маленький размер (35КБ) получается из-за сильной аппаратной поддержки виртуализации в MIPS R5. Для всего более раннего пришлось бы эмулировать полную работу с CP0, все привилегированные команды процессора в guest kernel.

              И к тому же, если не считать interAptiv/proAptiv, то на всех процессорах пришлось бы делать сильную паравиртуализацию, и первый этап — сборка ядра виртуальной машины в KUSEG вместо KSEG0, чтобы не эмулировать КАЖДУЮ команду процессора (на *Aptiv процессорах есть расширение сегментной памяти, которой позволяет гонять user-ный процесс в адресах KSEG0).

              За идеи по названию — спасибо.
            • 0
              Вот плата Olimex, которая очевидно будет следующей

              https://www.olimex.com/Products/PIC/Development/PIC32-EMZ64/open-source-hardware
              • 0
                Название Egoza
          • НЛО прилетело и опубликовало эту надпись здесь
            • 0
              Или MTH — MIPS Tiny Hypervisor
              • НЛО прилетело и опубликовало эту надпись здесь
                • 0
                  Спасибо.
              • +1
                VIPS — Virtualization without Interlocked Pipeline Stages
                VIPS for MIPS
                • 0
                  Спасибо. Хорошо бы еще букву-другую добавить, чтобы убрать ненужные ассоциации. Но идея тоже интересная.
                  • 0
                    Аналог HIPS — Hypervisor… маркетологи любят чтобы рифмовалось и размер совпадал. Другой подход — эксплуатировать идею IoT. HIoT — hypervisor for internet of things, HIT — если убрать of. Варианты VIT, VIoT.
                    • 0
                      Спасибо! Чувствуется, что где-то уже рядом.
                • 0
                  Назовите по имени того человка, которому мы обязаны словом «программа».
                  • 0
                    Определитесь: либо (общепринятый) «гипервизор», либо тогда уж «хайпервайзор».
                  • +2
                    hypervisor читается как гипервизор
                  • +1
                    Как всегда, приятно читать статью автора. Хорошие статьи.
                  • 0
                    Вообще-то Imagination утверждали что уже поддерживают KVM начиная с ядра «Knight».
                    • +1
                      Да, новый гипервизор Леонида Егошина не первый. Он просто самый маленький и заточен под MIPS M5150. Knight — это MIPS P6600.
                      • 0
                        Проблема в том, что в плату с 2MB ROM + 0.5MB RAM Linux c KVM не влезет. Да и если бы влез, то Linux в IoT девайс вы ставить не захотите.
                        • 0
                          Linux в IoT девайс вы ставить не захотите

                          Объясните, пожалуйста, почему?
                          • 0
                            Он имеет в виду ставить в loweest-power сенсоры для IoT. Ставить линукс в хабы для IoT или другие устройства для IoT инфраструктуры — это нормально
                            • 0
                              Исходный комментарий, по которому я задал вопрос, состоял из двух утверждений:
                              1. Вы не можете (не влезет)
                              2. Вы не захотите

                              Мой вопрос относился именно ко второму утверждению. Мечтать же никто не может запретить, а это действительно во многом было бы удобно. Но, пока, увы…
                              • 0
                                «Вы не захотите». Потребление энергии… смотрите на Android. И даже Nokia N900 с Meego вариантом Linux жрет энергии значительно больше, чем хочется.

                                Да и насчет security — полный швах в Linux-е. Его недаром на всех конференциях по security называют дипломатично Reach Execution Environment (REE) супротив TEE — Trusted Execution Environment.
                      • 0
                        не знаю насколько хорош вариант для названия, но пусть будет в комментах:
                        MiGEL = Mini-Hypervisor that is Egoshin's Labour :))
                      • 0
                        nanohv
                      • 0
                        Банкомат — это же суть ПК+windows, поэтому и вирусы.
                        Насколько мне известно, в серьезной банковской технике используется аппаратное разделение для функциональных блоков. Не виртуализация.
                        Например, за коммуникации и финансовые транзакции отвечают разные вычислители, хотя возможно и в составе единого SoC
                        В общем, не убедили для чего нужен ваш гипервайзер именно на микроконтроллере, тем более универсальном.
                        • +1
                          Аппаратная виртуализация — это как раз и метод аппаратного разделения функциональных блоков.

                          Насчет микроконтроллера — все просто, вы хотите гонять на нем две разных подсистемы от разных производителей, причем не доверяете обоим, ну упасть они могут токо-так. Надо восстановить упавшую, не уронив вторую. Пример — подсистема связи в сети и подсистема управления мотором. Или web сервер, типа в https://www.olimex.com/Products/PIC/Development/PIC32-EMZ64/open-source-hardware плюс еще что-то независимое, но критичное.

                          Можно конечно забацать SoC с двумя процессорами, стандартное решение. Но оно и энергии жрать больше будет, и его еще делать под задачу надо, придумывать систему удаленного сброса и т.п. И если для банкомата энергия не критична, то есть куча приложений, где это чувствительно. Да и стоимость чипа выше.

                          Софтверное разделение функциональных блоков на различные VM — это просто естественное расширение обыкновенной многозадачности, но с повышенной security.
                        • 0
                          MIPH — MIPS PHANTOM HYPERVISOR :)
                          • 0
                            Ну «фантом» — это вряд ли годится, гипервизор вполне реальный и уже работает. Пишу документы.
                          • 0
                            «с первой привезенной в Америку из России платой с российским микропроцессором Байкал-Т — Егошин помогал отлаживать на ней Линукс»

                            Можно узнать подробнее что он помог сделать для Байкал-Т?
                            • 0
                              Ну например там была проблема для префетчера в L2 кэше, он дистанционно помогал ее отлаживать; далее он давал байкаловцам рекомендации по максимизации производительности с помощью неких установок в Cop0 и других регистрах; наконец (это не только про байкаловцев но и про других пользователей ядер MIPS) он написал что-то в ядре Линукса.
                              • 0
                                Видимо Вас неверно информировали.

                                1. Ну скажем так префетчер там никак особо не обслуживается, есть команда prefetch для закачивания в L2 с физических адресов. Кое-где мы ее там использовали, но никакого обслуживания особого она там не требует.
                                Только L2 проинициализировать, чтобы ECC работало.

                                2. Про COP0 и оптимизацию ничего радикального не слышали — в первой версии ядра большинство фитч была перекрыта errata, максимум удалось задействовать спекулятивный режим работы с использованием MAAR, но это делали сами Байкальцы.

                                3. Про написание патчей в ядро тоже не особо видно, Леонид там больше выступает как ревьювер. С 2015 года Imagination ведет определенную активность в ветке MIPS, в основном для последних ядер, но патчи шлют другие люди.

                                • 0
                                  О, я совершенно не утверждаю, что Егошин делал чего-то много для Байкала. Я в курсе, что ваша группа сама все отладила. Я видел со стороны, как он делал что-то на байкаловской плате (насколько я понял теперь, он делал на ней Fiasco) + был в CC по поводу проблемы с производительностью префетчера (не связанного с командой prefetch) (префетчер ждал завершения операции на шине перед генерацией другого запроса, что он делать не должен). Егошин по этому поводу послал пару емейлов с общими соображениями о повышении производительности. Леня работает в другой группе, поэтому я деталей его работы не знаю. Знаю, что он участвовал в Линуксе и Андроиде.
                                  • 0
                                    Может не будем ссориться или меряться у кого больше?

                                    Я же не собираюсь у вас отнимать авторство (я так понимаю, что вы один из разработчиков, да?). Но то, в первых версиях не был включен L2 prefetch в первом варианте ядра Linux, и для данных и для кода, UBoot гасил Config.MM и производительность падала, MAAR не были сконфигурены (30% при копировании), FTLB был выключен — это факт, а включили ли вы bonding — я до сих пор не в курсе.

                                    Но я не ставлю вам это в вину, в конце концов это в наших интересах помочь вам все это запустить.

                                    Что же касается патчей в ядро Linux, то я рекомендую вам обратить внимание на — https://git.linux-mips.org/cgit/yegoshin/mips.git/log/ — там все правки в ядро, которые я разработал в оригинальном варианте, включая EVA, MIPS R6, эмуляцию MIPS R2, все кэш flash правки (! рекомендую очень внимательно на них посмотреть, это важно!), GIC, защита стэка от выполнения команд, поддержка всех процессоров с 1004K до P5600 и многое другое. Увы, не все вошло upstream, а многое из того, что было сделано было переделано другими людьми под предлогом «несоответствия стандартам», хотя мне даже приходилось их пинать, чтобы хоть что-то сделали. Там только нет моей версии Power control — он не использует общий драйвер из-за его ошибочности и неэффективности, но мне прямо запретили этим заниматься в Linux ядре.

                                    С 2015 я работаю над другими проектами.
                                    • 0
                                      > Но то, в первых версиях не был включен L2 prefetch в первом варианте ядра Linux, и для данных и для кода
                                      А Вы уверены в стабильности его работы?
                                      Кажется, никому не хочется смотреть на креш дамп при обмене с SATA.

                                      > UBoot гасил Config.MM и производительность падала
                                      Естественно — как и было в errata от Imagination

                                      > MAAR не были сконфигурены (30% при копировании)
                                      Еще раз про стабильность. Проверяли?

                                      > FTLB был выключен — это факт
                                      Про это подробнее. Какая версия SDK?

                                      > а включили ли вы bonding — я до сих пор не в курсе.
                                      В последней версии — да, а до этого — см. errata от Imagination

                                      Про авторство и патчи — как-то абсолютно без разницы сколько их написано и для чего они. Просто формально патчи эти никак не повлияли на подъем Linux на Байкале. А изначальный посыл у «пиарящегося товарища» был именно такой :)
                                      Кстати, мы долго пользовались своими драйверами GIC/GCR/CPC до момента пока в маинстриме это все не стало более-менее стабильно на SMP (и все равно GIC время от времени ломают — как было, например в 4.6).
                                      • 0
                                        > А Вы уверены в стабильности его работы?

                                        Я вообще-то гонял soak-тесты 3 недели на P5600 на Malta начиная с первых релизов, плюс массу других тестов раздельно и совместно. И сидел на шее у HW команды, доказывая им, что у них ошибка.

                                        Но это было на 3.10.72 из моего репозитария на LMO. Если хотите убедиться, что проблема в SW а не в HW — погоняйте на этой версии, я специально ее еще держу и даже слегка поддерживаю, чтобы в критической ситуации можно было точно понять, кто виноват. Раз 5 уже пригодилось :)

                                        > Кажется, никому не хочется смотреть на креш дамп при обмене с SATA

                                        Единственное, что я тут могу сказать, что см мои правки. Я устал добиваться того, чтобы они прошли upstream.

                                        > MAAR: Еще раз про стабильность. Проверяли?

                                        Еще как! Но опять-таки — см мои правки, upstream до сих пор не содержит много насчет кэша. Долгое время они вообще конфигурили MAAR только на одном процессоре. А уж правки насчет агрессивного dataload/ifetch ядром Linux-а до сих пор непонятно в каком состоянии, см разницу в функции flush_icache_page() например.

                                        > Просто формально патчи эти никак не повлияли на подъем Linux на Байкале.

                                        Мы с Панчулом в «отладку» включаем обычно стабильность и эффективность, посему он так и написал. Напечатать Hello Word конечно очень большое дело, но это еще не конец. Собственно я только этим и занимался — проглядел код, который мне прислали, отметил проблемы и написал обратно в компанию. А потом компания еще ко мне пару раз обращалась насчет эффективности. А я им писал насчет пропущенных кусков насчет стабильности.

                                        > Кстати, мы долго пользовались своими драйверами GIC/GCR/CPC до момента пока в маинстриме это все не стало более-менее стабильно на SMP (и все равно GIC время от времени ломают — как было, например в 4.6).

                                        Увы, тут я только могу разделить с вами ваше негодование. После того, как весь этот код был исковеркан… увы. Как известо, 4.0 вообще не смог загрузиться на general MIPS, пришлось делать экстренные правки — представляете себе качество разработки! Майнстрим мне никак не подчиняется, критические патчи на стабильность сидят в LMO годами, пока кто-нибудь типа вас крик не поднимет.

                                        И вообще — вы будете в головном офисе в RigaLand 10-го? Можем встретиться лично и поговорить подробно, тут мне не все удобно рассказывать.
                                        • 0
                                          > Я вообще-то гонял soak-тесты 3 недели на P5600 на Malta начиная с первых релизов, плюс массу других тестов раздельно и совместно. И сидел на шее у HW команды, доказывая им, что у них ошибка.

                                          Первый P5600 на Malta у нас был весьмы странный. Там даже был GIC, но в силу архитектуры Malta никуда не подключался :)

                                          > Я устал добиваться того, чтобы они прошли upstream.
                                          А что говорит Ральф? Хотя, кажется я знаю. Он хочет посмотреть их стабильность на реальном железе, а у него нет ни интераптива, ни p5600. Это, кстати, одна из причин, почему Байкальского кода нет до сих пор в маинстриме.

                                          > И вообще — вы будете в головном офисе в RigaLand 10-го? Можем встретиться лично и поговорить подробно, тут мне не все удобно рассказывать.

                                          Постораюсь быть. Вчера мне анонсировали Ваш приезд.
                                          • 0
                                            > Там даже был GIC, но в силу архитектуры Malta никуда не подключался :)

                                            Ну к Интел-овскому контроллеру прерываний-то он подключен :)
                                            Ну и Bus Err из CM обязан принимать.

                                            > А что говорит Ральф? Хотя, кажется я знаю. Он хочет посмотреть их стабильность на реальном железе, а у него нет ни интераптива, ни p5600. Это, кстати, одна из причин, почему Байкальского кода нет до сих пор в маинстриме.

                                            Можем поговорить об этом в оффисе. MIPS R6 нету не только у него, между прочим, а правки есть (хотя и кривые). А уж насчет правок работы с кэшем — я гарантирую, что SMP системы с CM у него _есть_, а правок не было… до тех пор, пока их не представил JamesH, и посему — неполные. И т.д и т.п. — типичный междусобойчик.
                                • 0
                                  … Портировал первую версию KernKonzept гипервайзера (Fiasco/L4Re) на неё…
                                  • 0
                                    Вместе с Адамом?
                                    • 0
                                      До. Он в это время все переделывал а нам срочно нужна была презентация, пусть и на старом варианте.

                                      Да и слабоваты они тогда в архитектуре MIPS-а были, хотя учились быстро.
                                • +1
                                  он единственный на фотке на Красной Площади 1980-х, кто улыбается
                                  Да ну, единственный кто широко улыбается, почти смеётся, а ещё пара улыбающихся там точно есть (если не считать полуулыбки, со слегка приподнятыми уголками рта)
                                  • 0
                                    Спасибо всем за идеи. После ряда консультаций выбрано имя tinyVP — tiny Virtual Platform.
                                    Исходные тексты выложил на github:

                                    https://github.com/lyegoshin/tinyVP

                                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.