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


Хочется сказать спасибо art_zh за потраченное время на подготовку материала для данной статьи.

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

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

Один из наших разработчиков — art_zh, инженер-электронщик из Англии, пришел в проект после долгих и безуспешных поисков оптимальной ОС для системы «быстрого» технического зрения на х86-платформе. Конкретная задача требовала обработки широкополосного видеопотока (500 SXGA-кадров, 660 миллионов пикселей в секунду), – из этой лавины данных нужно было выделить несколько характерных зон, найти среднюю яркость в каждой зоне и следить за изменением этой яркости в течение 10-12 часов. Периодически отображая полноформатную картинку на экране.



Задача осложнялась нестандартностью применяемого железа. Фреймграббер и DMA-контроллер были реализованы на экспериментальной PCI-express карте с мотором Virtex-5 от Xilinx. Суровый Verilog-код требовал тщательной отладки всех пакетных транзакций протоколу TLP-PCIe. Эту тему мы более подробно обсудим в одной из следующих публикаций этого цикла, здесь ограничимся констатацией того, что среда Windows для такой отладки представляется совершенно непригодной, а в Линуксе цикл модификация кода — компиляция драйвера – перезагрузка – анализ printk-сообщений занимал неприемлемо долгое время.

Итак, нужна была быстрая, графическая, 32-разрядная операционная система с экзоядром, прозрачным для доступа из приложения к аппаратным ресурсам самого низкого уровня – конфигурационному пространству PCI, регистрам PCIe Root Complex, адресам MMIO (отображаемого на память ввода вывода) и т.п.

КолибриОС привлекала своей быстротой и минимальной латентностью, простым и удобным графическим интерфейсом, очень компактным и открытым кодом ядра. Проблема была с ограниченным набором функций для работы с аппаратной частью ПК.

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

Так появилась Колибри-А, экзоверсия КолибриОС для платформ на базе AMD Fusion. Поскольку любое экзоядро несет в себе опасность фатального повреждения данных и оборудования ПК из-за некорректного доступа к критическим системным ресурсам, а также учитывая, что подавляющее большинство пользователей нашей системы – чайники малоопытные пользователи, пробующие новые ОС из чистого любопытства, Колибри-А изначально позиционировалась как совершенно обособленная ветка КолибриОС, предназначенная только для квалифицированных юзеров, имеющих представление как и с какими устройствами можно (и как нельзя) обращаться, и несущими полную ответственность за последствия своих действий.

Первым делом приложению напрямую был открыт доступ к
  1. Вводу/выводу во все порты (в основной ветке ядра приложение до сих пор должно «заказывать» нужный диапазон портов ввода/вывода через уродливое менуэтовское наследие – т.н. «сороковые функции»).
    Этого оказалось мало. Сейчас уже трудно найти устройство, общающееся с процессором исключительно через порты. Был добавлен удобный
  2. Доступ к MMIO (отображаемому на память пространству ввода/вывода) с помощью сисфункции 62:12. Сервис работает подобно линуксовской функции ioremap(), но реализован проще и гибче. Приложение указывает номер BAR-регистра в конфигурационном пространстве выбранного устройства и выбирает диапазон MMIO, к которому будет обращаться, а ядро отображает выбранный диапазон на линейное пространство приложения.
    Но и это еще не все. Приложение должно иметь полный доступ к конфигурационному пространству выбранного устройства. PCI-сервис ядра КолибриОС был реализован через медленные и неудобные порты CF8/CFC. В А-версию был добавлен быстрый доступ к
  3. Конфигурационному пространству PCI (включая расширенный конфигспейс PCI Express) с отображением на виртуальное адресное пространство приложения начиная с адреса 0xF0000000. Пример чтения заголовка PCI-устройства 1:18:2
    mov  eax, (1 shl 20) + (18 shl 15) + (2 shl 12)
    or   eax, 0xF0000000
    mov  [device_vendor], [eax]

    Нужно заметить, что отображение конфигспейса на память реализовано только для платформ на базе AMD-процессоров (кстати, именно это подчекивает название «Колибри-А»). Для интелов экзосервис пока не разработан: art_zh работает только с AMD-железом, а все остальные разработчики, к сожалению, особого интереса к экзоядру не проявляют.
    Ну хорошо, конфигспейс открыт. Теперь мы можем идентифицировать устройства, разрешать прерывания, следить за состоянием PCI-линии и обращаться к любым внутренним ресурсам, контролируя потоки данных и организуя прямой доступ в память… Хотя тут вот есть неувязочка: устройство ведь знает только физические адреса DMA-области, а приложение живет в своем линейном пространстве. Для этого
  4. Выделена статическая область DMA. Используя специальную сисфункцию 62:12-DA, приложение может запросить ее линейный адрес и работать с ней напрямую:
    mcall  62,11,0x0500                     ; init MMIO/DMA: bus=5, device=0, fn=0
    mov  [dma],eax                           ; store phys.addr of the DMA buffer: 
    mcall 62,0+12,4096,0                  ; map MMIO access to BAR0-space
    mov  [mio],eax                            ; store MMIO linear address
    mcall 62,0xDA0C,4096,0              ; 0x0da0c = create user DMA channel
    mov  [mem],eax                          ; store DMA buffer: linear @
    mov  eax, [dma]
    or   eax, DMA_FLAGS
    mov  dword[mio+4], eax              ; program device-specific DMA-register
    ;  ....
    mov  ecx, [mem]
    mov  eax, [index]
    mov  edx, dword[ecx+eax*4]       ; load the fresh data from DMA-buffer

    Вот теперь с устройством можно полноценно работать прямо из пользовательского приложения. Получился гибкий и универсальный инструмент, который art_zh уже 5 лет использует в повседневной работе для разработки нового железа и отладки низкоуровнего кода очень разных встраиваемых х86-устройств.
    К сожалению, разработав такой инструмент, автор переключился на другие задачи и нечасто публикует новые версии своего кода (оставаясь в проекте в роли «продвинутого юзера» и вечного брюзги на форуме). Но несмотря на длительные перерывы, работа потихоньку продолжается. Кроме вышеперечисленных, на сегодняшний день в Колибри-А имеются и другие экзофишки:
  5. Организация MSI-прерываний может быть организована через доступное юзеру адресное пространство LAPIC.
  6. Физическая память также может быть прочитана из приложения. Этот сервис очень полезен при отладке ядра.
  7. Бездисковая загрузка ОС опробована через CoreBoot (с помощью Xvilka) и через BIOS Extension ROM – из бортовой памяти PCIe-устройств.
  8. Открыто пространство GPU – пока только для установки аппаратных курсоров и реверс-инжиниринга ресурсов графического процессора AMD/ATI. Но кто знает, возможно когда-нибудь в Колибри будут программы и на GPU-ассемблере...


(продолжение следует)

Комментарии (11)


  1. Alexsmt
    17.06.2015 04:11

    Интересно, что помешало реализовать остальную сверхскоростную часть внутри FPGA в виде связки быстрой логики (что-то вроде двухпортовая RAM + логика + конечный автомат + если надо DSP) + встроенного в чип PowerPC для общей координации процесса, если фреймграббер уже реализован.

    Хотя вопрос наверно не к вам, и у него были причины переносить обработку изображения на «ранних стадиях» на CPU.


    1. art_zh
      17.06.2015 20:05
      +1

      Самый ценный ресурс — время.
      Отлаживать CPU-код (особенно на PC!) гораздо легче и быстрее, чем городить сигнал-процессинг внутри ПЛИС.
      На последующих стадиях разработки, когда заказчик уже убедился что железяка реально работает и готов раскошелиться на оптимизацию — тогда да, значительную часть DSP можно спокойно упаковать в ПЛИС и портировать в Линукс или винду.


  1. splav_asv
    17.06.2015 10:52
    +1

    а в Линуксе цикл модификация кода — компиляция драйвера – перезагрузка – анализ printk-сообщений занимал неприемлемо долгое время

    А зачем именно перезагрузка? Возможно, я что-то не понимаю, но модуль же можно выгрузить и загрузить новый без проблем.


    1. Veliant
      17.06.2015 13:08
      +2

      Передаю ответ art_zh из чата на форуме board.kolibrios.org

      в том смысле что на ранних этапах разработки новое, неотлаженное PCIe-устройство часто виснет само и вешает всю систему.
      пока не будут выловлены все баги (и в драйвере, и в ПЛИС) — приходится перезагружаться сотни раз


      1. splav_asv
        17.06.2015 14:32

        А, тогда понятно. В таком случае Колибри чем выигрывает — не виснет намертво или быстрее перезагружается?


        1. Punk_Joker Автор
          17.06.2015 19:00

          Гораздо быстрее перезагружается: 3-5 сек


          1. splav_asv
            17.06.2015 19:09

            Ясно. Более классический вариант для таких целей — удаленная отладка по сети. Загрузка до консоли соизмерима по скорости, может раза в 1.5-2 дольше.


        1. ion2
          17.06.2015 19:09

          Очень быстрый цикл компиляция — перезагрузка.


        1. art_zh
          17.06.2015 19:34
          +2

          Во-первых, быстрее перезагружается (POST+BIOS + 2 секунды),
          а во-вторых, с экзоядром отпадает необходимость в отдельной компиляции отладочного драйвера кернелспейса — printk-прослойки между отлаживаемым приложением и налаживаемым железом.
          (у кода — отладка, у аппаратуры — наладка. Хотя, если железо построено на ПЛИС, то наверное и там тоже правильнее говорить «отладка»?)


  1. balamut108
    17.06.2015 11:04
    +1

    Испытываю громадное уважение к таким проектам. Ребята вы молодцы! Продолжайте!


  1. ion2
    17.06.2015 19:18
    +1

    Добавлю про GPU. К сожалению, единственный реальный путь к использованию GPU ATI/AMD лежит через портирование LLVM. Первая попытка закончилась неудачно, но я не теряю надежды.