Краткое содержание: разработка модуля совместимости с ОС Колибри внутри модуля совместимости с ОС Юникс внутри ОС Фантомь)

Внутри ОС Фантом есть маленький простенький Юникс. POSIX подсистема. В принципе необязательная для работы самого Фантома и довольно неполная — Unix Quake под ней собрать удалось, а, например, апач не соберётся почти наверняка. Тем не менее — она есть.

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

Почему же, тем не менее, любопытно реализовать слой совместимости с этой ОС? Тому несколько причин:

  • Она очень компактна. Забегая вперёд — первую программу для Колибри в Фантоме удалось запустить через четыре часа работы.
  • Этот мини-проект стал драйвером развития некоторых нативных подсистем Фантома,
    в частности — оконной.
  • Главное — всё состояние процесса Колибри, известное ядру, укладывается в небольшую структуру. Многие (почти все!) вызовы — stateless, то есть не опираются о какое-либо знание,
    хранимое в ядре. Это идеальный кандидат на реализацию персистентных (переживающих перезапуск ОС) бинарных (не написанных на байткод-языке) процессов в Фантоме.

Для любопытных, код, хедер.

Собственно, разработка слоя совместимости делится на несколько очевидных частей:

  • Загрузчик исполняемого образа
  • Точка входа в системный вызов
  • «Прокладки» для системных вызовов, конвертирующие их в семантику существующих компонент системы
  • Разработка недостающей функциональности

Загрузчик образа Колибри тривиален, за исключением реализации запуска запакованных программ. К сожалению, реализация распаковки по имеющимся фрагментарным спекам к успеху не привела, и найти кого-то, кто разбирается, не удалось. Непакованные программы устроены очень просто, так что детектирование и загрузка образа дополнили существующий elf-овский загрузчик без проблем. Кстати, под Фантом программы для Колибри можно компилировать и обычным elf-овским тулчейном — вне зависимости от того, какой загрузчик загрузил программу, она может обращаться и к системным вызовам POSIX, и к Колибри. Можно вперемешку )

Точка входа тоже ничего неожиданного не представляет — вызовы делаются через программное прерывание, обычный IDT gate и небольшой ассемблерный трамплин решают задачу.

Основная работа, конечно, это реализация системных вызовов. Работа трудоёмкая по двум причинам — во-первых, вызовы документированы схематично, во-вторых, их создатели реально не утруждали себя какой-либо консистентностью. Для примера — вызов запроса информации о процессе в одном из полей возвращает… номер другого процесса, окно которого находится в заданной z-позиции на экране.

Реализация вызовов делалась по принципу «типа TDD»: вместо реализации системного вызова просто пишем в лог ошибку, запускаем прикладные программы, если вызван не реализованный системный вызов, реализуем то, что было вызвано. Так что если колл не сделан, значит я не дошёл до прикладной программы, которая в нём нуждается.

В целом вызовы делятся на несколько групп.

Информационные


С ними всё просто. Ещё и потому, что часть информации можно выдать в константном или фейковом виде. Хороший пример — st->eax = dummy++; // TODO n of context switches — возрастает, и ладно. Где возможно, конечно, информация выдаётся реальная.

Low-level


Колибри — система почти без защиты, процесс может очень много, в том числе — модифицировать регистры процессора, обычно доступные только ядру. Большинство таких вызовов, конечно, просто не реализованы.

Файловые операции


Файловые операции Колибри более-менее консистентны (как минимум, коды ошибок одни и те же), но реализация их весьма дорогостояща — все они не хранят в ядре практически никакого состояния и, де факто, сводятся к группе open / do / close. То есть, чтение из файла на каждый вызов выполняет открытие и закрытие файла. В принципе, это можно попробовать оптимизировать через hash map имени файла и держать пул открытых дескрипторов, но в скоуп проекта выходного дня это уже не входит. Я не делал. В остальном реализация более-менее тривиальна.

Графика


Тут я ожидал проблем. Они и были, но, в основном не столь жуткие, как могло бы случиться. Впрочем, есть ощущение, что представления авторов графической подсистемы Колибри до конца я всё равно не постиг — некоторые программы работают нормально, некоторые — странно. Увы, без того, чтобы реально читать исходники оригинальной реализации, наверное, прогресс тут невозможен, а исходники, я напомню, на ассемблере. Я не нашёл в себе достаточно куража, и остановился на том, что какое-то подмножество программ работает нормально.

Главное отличие графики Колибри в том, что ядро реализует часть традиционно прикладных компонент окна — в частности, кнопки. Готовой ответной части в оконной системе Фантома не было, пришлось писать. Очевидно, прикладной код Колибри жёстко завязан на конкретные шрифты, применённые в ядре — шрифты пришлось извлечь и конвертировать в формат оконной подсистемы Фантома, плюс несколько доработать код визуализации шрифтов. Были и другие мелочи, в целом несущественные.

Реализовано, но не протестировано


Колибри поддерживает несложный механизм IPC — почтовые ящики. Он реализован схематически, но подробному тестированию не подвергался. Реализован также запуск дополнительных тредов процесса — тоже без серьёзного тестирования. Кстати, не вполне очевидно, какая часть состояния ядра должна относиться к процессу, а какая к треду.

Отсутствует


Полностью не реализованы функции управления отображением памяти — в настоящее время ядро Фантома работает только с одним адресным пространством (процессы Юникса и Колибри поддерживаются через механизм сегментной адресации x86), поэтому их не на что отображать. В силу этого же факта трудно (хотя и можно) реализовать изменение размера адресного пространства процесса. Не реализована поддержка DLL -сама Колибри ими пользуется очень неактивно, а план был в том, чтобы сделать минимум необходимого. Впрочем, это не представляется сложным.

Развитие проекта


Довольно очевидно, что для продолжения работ требуется:

  • Набор регресс-тестов. Желательно в виде а) внутренних юнит-тестов для компонент;
    б) специальных тестовых прикладных программ и в) прогона существующих программ с контролем их работоспособности.
  • Ревью кода опытным разработчиком ядра Колибри на предмет соответствия реализации оригиналу
  • Ревью кода на предмет подробной верификации всех точек входа Колибри-Фантом на предмет допустимости и осмысленности параметров.

В общем, нужен герой из команды разработчиков ОС Колибри. I need a hero :)
Поделиться с друзьями
-->

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


  1. domix32
    25.07.2017 14:32

    Какая-то проблема с кодировкой в репозитории


    1. dzavalishin
      25.07.2017 16:06

      спасибо. там 866, конечно. :) Сделаю utf8.


    1. dzavalishin
      25.07.2017 16:07

      fixed, thanx


  1. Ghost_nsk
    26.07.2017 09:43
    +3

    Вызовы делаются не только через прерывания. Много лет назад я добавлял быстрые системные вызовы sysenter / syscall.
    Тогда во многих программах системные вызовы были переделаны на макрос mcall, который в зависимости от настроек мог генерировать разные варианты. Возможно из за этого какие то программы не работаю.
    Распаковку приложений я делал примитивно, запускал до первого системного вызова. Потом весь дамп сохраняем, правим заголовок и получаем распакованное приложение.
    Давно все это было, приятно вспоминать. Сейчас даже не представляю в каком состоянии проект.


    1. dzavalishin
      26.07.2017 12:07
      +1

      Айда к нам, в Фантом. Тут есть прорва задач на ядерном уровне.


  1. ninacarrot
    26.07.2017 13:53

    Вы ошибаетесь насчёт библиотек, любая мало-мальски серьёзная программа в Колибри без них просто не запустится.