Как Вы уже знаете, система построена на базе микроядра L4 и состоит из набора процессов, осуществляющих различные функции операционной системы. Почему выбрано микроядро L4? Микроядро L4 - это микроядро второго поколения, которое реализует стройный, неперегруженный и, что немаловажно, отлично документированный набор системных вызовов. Микроядро L4 предоставляет следующие механизмы - синхронные IPC, динамически создаваемые и осовобождаемые адресные пространства, механизм <Lazy scheduling>, вызовы управления программными потоками.
Xameleon использует стандартную схему загрузки микроядра. Процесс загрузки происходит следующим образом. Загрузик grub читает файл /boot/grub/menu.lst, в котором находится список модулей для начальной загрузки.
title = Xameleon on L4Ka::Pistachio/ia32
kernel=/boot/kickstart.gz bootinfo=on mbi=on decode-all=on
module=/boot/ia32-kernel.gz
module=/boot/sigma0.gz
module=/Supervisor
module=/tty.drv
module=/rs232.drv
module=/ramdisk.drv
module=/floppy.drv
module=/ide.drv
module=/FileSystem.drv
module=/init initrd
Затем grub последовательно загружает модули в оперативную память и формирует запись MBI, которая впоследствии используется модулем kickstart и Supervisor. Наконец, загрузчик передаёт управление модулю kickstart.
kickstart - первый модуль микроядра L4Ka::PIstachio. Он стартует микроядро, которое расположилось в файле ia-32kernel. Третий модуль - сервер виртуальной памяти sigma0. В момент инициализвации sigma0 становится владельцем всей оперативной памяти в системе. Этот сервер поддерживает простейший протокол, который умеет только отдавать страницы физической памяти в адресное пространство запрашивающеuj процесса и обрабатывать запросы на выделение памяти микроядром. Собратите внимание, что протокол sigma0 не поддерживает комманды для освобождения страниц, т.е. страницу нельзя вернуть серверу sigma0 и запросить её поторно.
Модули kickstart, kernel и sigma0 входят в микроядро L4Ka::Pistachio и распрстраняются под лицензией BSD.
Базовый модуль, с которого начинается Xamleon, называется Supervisor. Он отвечает за управление виртуальной памятью и за управление процессами и программными потоками. В терминах спецификации L4 этот модуль именуется roottask. Supervisor стартует первым после модулей микроядра и анализирует блок MBI. На основе из информации MBI, Supervoisor старует найденные модули. Запуск модулей происходит паралельно, на основе оригинального стартового протокола. Помимо этого, Supervisor реализует основной цикл обработки запросов управления потоками, процессами и памятью. При разработке Supervisor использованы оригинальные алгоритмы хранения объектов - используется совмещённая модель массивов и списков, которая обладает достоинствами обеих подходов хранения данных. Однотипные структуры данных, такие как объекты управления процессами или объекты управления программными потоками, хранятся в потоках виртуальных страниц. Каждый поток виртуальных страниц предоставляет динамически растущий массив однотипных данных, чей размер ограничен лишь размером физической памяти. Таким образом, с точки зрения драйвера, объекты хранятся в массиве. При этом отпадает необходимость динамического выдедения памяти. С другой стороны, элементы массива обладают свойствами списков и связвают элементы массива по различным критериям. В то же время, память под массивы выделяется постранично (для платформы x86 размер страницы составляет 4Кб), соответсвенно, алгоритм выделения памяти для массива более прост, менее ресурсоемок и более быстр, чем традиционные алгоритмы выделения памяти произвольного размера.
Следует отметить, что вышеописаный подход не отменяет динамического выделения памяти произвольного размера на уровне пользовательских задач. Пользовательские задачи используют традиционный malloc(), выделяющий память задаче в её сегменте BSS через системный вызов sbrk(). Xameleon использует библиотеку работы с динамической памятью, написанную Владимиром Давиденко.
В текущей реализации системы драйвера устройств и протоколов работают в адресном пространстве супервайзера. Однако, протокол инициализации драйвера поддерживает работу драйвера в индивидуальном адресном пространстве, что позволяет строить защищенную систему, устойчивую к взломам и ошибкам в драйверах.
Одним из первых драйверов, написанных для Xamelon, является драйвер виртуальных консолей - vty.drv. Этот драйвер является драйвером последовательного устройства и поддерживает протокол обмена данных последовательных устройств. После старта он регистриует шесть виртуальных консолей /dev/vty0 - /dev/vty5. Переключение между консолями аналогично подобной операции в Linux и FreeBSD - успользуйте комбинаци клавиш Alt+F1 - Alt+F6 для переключения между виртуальными консолями. Консоли поддерживают ANSI совместимый набор команд, которые позволяют управлять курсором, цветом выводимых символов и другими параметрами. Помимо этого, консоли также поддерживают termios совместимые ioctl для управления режимами работы последовательного устройства.
Хорошим примером блочного устройства является драйвер виртуального диска. Это простейшая программа, которая предоставляет доступ к операциям чтения и записи логических секторов образа виртуального диска. Виртуальный диск представляет собой логический образ диска, отформатированный в формате файловой системы Minix, затем сконвертированный в объектный файл и прилинкованый к коду драйвера. Информация о содержимом виртуального диска описана ниже в данном документе.
Если процесс Supervisor рассматривать как сердце системы Xameleon, то драйвер файловой системы - её мозг. Драйвер FileSystem предоставляет надмножество Posix совместимых системных вызовов, которые доступны прикладным программам и драйверам при использовании оригинальной libc. Помимо этого, модуль FileSystem предоставляет поддержку различных файловых систем. Мы используем объектно-ориентированную модель реализации движков файловых систем. Объекты поддержки любой файловой системы наследуются от базового класса Superblock, который поддерживает реализацию базовых примитивов функций файловой системы. Фактическая реализация примитивов и понятий конкретной файловой системы объявлена через абстрактные методы. Таким образом предоставляется поддержка следующих файловых систем: Minix, Ext2, FAT12/16/32, ISO9660. Поддержка других файловых систем может быть реализована при наличии подробной спецификации. Кроме того, FileSystem.drv поддерживает оригинальную devfs.
Следует особо отметить, что драйвер файловой системы реализует однопоточную асинхронную модель поверх синхронных IPC. Чтобы понять это утвержение рассмотрим сначала однопоточную синхронную модель. В Этом случае каждый процесс или поток может выполнить операцию чтения/записи только после того, как будет обработан предыдущий запрос от другого процесса или потока. Поскольку операция доступа к блочному устройству может занять длительное время, то одновременный доступ к такому устройству может занять длительное время. Более того, при чтении данных из последовательных устройств, процесс может заблокировать запросы других процессов/потоков вполть до реакции оператора, например, до нажатия клавиши. Поэтому в настоящее время распространены два типа реализации системных вызовов - первые системы исполняют системный вызов в том же потоке, что и процесс/поток запроса, при этом переключив систему привелегий задачи на уровень системы. Такой подход неприменим для микроядерных систем, поскольку в микроядерных системах системные вызовы реализованы через IPC. Поэтому другим, часто используемым подходом, является создание нескольких потоков на уровне ядра системы и диспетчеризация запросов между этими потоками. Данный подход требует значительных затрат на синхронизацию доступа к общим ресурсам, например, к дисковым кешам.
Как уже сказано выше, система Xamelon использует однопоточную асинхронную модель. Представим обработчик системных вызовов файловой системы как фильтр между пользовательсой задачей и драйвером блочного устройства. Особенностью данного фильтра является контекст запроса. Используя контекст запроса, фильтр, получив запрос от пользовательской задачи, как можно быстрее обрабатывает запрос и формирует запрос для нижлежащего драйвера - в данном случае драйвера блочного устройства. Самое интересное начинается после отправки запроса блочному устройству. Фильтр не дожидается конца выполнения запроса, а переходит в состояние ожидание любого события. Причём, этим событием может быть как ответ блочного устройства, так и новый запрос от другой пользовательской задачи. При такой схеме фильтр может получить ответ от блочного устройства, запрос которому был направлен гораздо ранее. В этом случае используется контекст запроса и ожидающей задаче отправляется подверждение. Иными словами, задча фильтра - как можно быстрее обработать запрос и передать его по цепочке дальше и при получении ответа, выслать подтверждение запроса (возможно, вместе с полченными данными) процессу, инициатору запроса. Такая схема имеет как минимум два преимущества по сравнению с традиционными реализациями системных вызовов - асинхронный доступ к данным и отсутствие необходимости защиты данных от одновременного доступа несколькими программными потоками.
Вымученный, но так до конца и не отлаженный драйвер - драйвер контроллера IDE, поддерживающий ATA/ATAPI устройства. Драйвер анализирует ATA устройства, имеющиеся в компьюетере, затем анализирует MasetrBootRecord каждого найденного устройства и создаёт файл блочного устройства для каждого найденного логического диска. Информацию о найденных логических дисках можно увидеть на второй виртуальной консоле после загрузки системы.
Несмотря на то, что IDE драйвер поддерживает режимы BUS Master DMA, в демонстрационной версии драйвер работает в режиме PIO. В дальнейшем планируется реализовать в драйвере схему "лифта", при которой запросы на ввод/вывод обрабатываются не в очереди поступления, а а в порядке потимального движения магнитной головки жесткого диска. Кеширование некоторых структур данных реализовано в драйвере файловой системы. Дальнейшее кеширование планируется реализовать в виде промежуточного кеш-драйвера, который встривается между файловой системой и драйвером устройства.
Во второй публичной сборке системы появились два новых драйвера, драйвер контроллера флоппи диска и драйвер последовательного порта. Дравйвер floppy.drv позволяет производить операции чтения/записи на дискету. Обратите внимание, драйвер никогда не тестировался на реальном железе, а только в среде виртуальной машины. Поэтому могут проявиться проблемы с мотором привода. В текущей сборке демонстрационного диска Xameleon, корневая файловая система демонстрационого диска монтируется в каталог /floppy. Таким образом Вы имеете возможность просмотреть файлы демонстрационного диска непосредственно из системы. Файл устройства файловой системы - /dev/fd0
Драйвер последовательного порта rs232.drv реализует функцию виртуального терминала на последовательном порту. Файл устройства последовательного порта /dev/com1. В настоящее время драйвер предоставляет доступ только к первому коммуникационному порту. Драйвер последовательного порта, также как и драйвер виртуальных консолей, поддерживает posix termios. Оба драйвера используют библиотечный класс, реализующий Line Discipline. В текущей версии системы класс Line Disciplne вынесен в библиотечную функцию, что позволяет на его базе реализовывать драйвера различных устройства с последовательным доступом.
Файловая система, находящаяся на виртуальном диске, при загрузке Xameleon монтируется в корень. Использутся юниксоподобная структура каталогов. В каталоге /bin вы обнаружите несколько исполняемых файлов. Все из них, кроме deco, являются хардлинками на файл sh. (Идея взята из реализации busybox). Поскольку система Xameleon пока не поддерживает динамически загружаемые библиотеки, использование одного исполняемого файла для реализации различных системных утилит позволяет экономить дисковую память. Следует обратить внимание на то, что на данном этапе sh, который Вы обнаружите на диске, не является полноценным шеллом - он не поддерживает скриптовый язык и не умеет перенаправляеть поток ввода/выода. Пока он лишь служит для запуска программ. Кроме того, процесс sh автоматически не стартует после инициализации системы. Для первоначального старта sh необходимо набрать exec /bin/sh в тестовом процесс (в данном случае он назывется init, его Вы узнаете по приглашению #).
Другой программой, которую Вы найдёте в каталоге /bin, будет Demos Commander (deco). Demos Commander написан Сергеем Вакуленко в 1987. Это первая, и на настоящий момент единственная, программа, портированная на систему Xameleon. В настоящее время deco распространяется под лицензией GNU.
Официальная страница Demos Commander: http://sourceforge.net/projects/deco/.
В каталоге /sbin Вы найдёте два исполняемых файла - fault и L4_Proj.exe. Первый использовался для отадки различных системных вызовов. Вряд-ли Вам понадобится его использование. Второй файл более интересен. Как Вы заметили, этот файл имеет расширение .exe. Он собран при помощи Microsoft Visual Studio и использует хамелеоновсвкую библиотеку libc, также откомпилированную при помощи Visual Studio. При его запуске на все виртуальные консоли выводится строка "Hello!!!". Как этого удалось достичь? Драйвер файловой системы включает в себя парсер двух файловых форматов - это Elf, который является стандартом для юниксоподобных систем и формат WinPE, который используется компанией Microsoft. По сути, все форматы исполняемых образов имеют общую логическую структуру - сегменты, секции и различные таблицы. Парсеры исполняемых файлов системы Xameleon на этапе загрузки исполняемомго файла приводят его формат ко внутреннему формату, используемому в Xameleon.
Отладочный программный поток активирован на виртуальной консоле /dev/vty3. Для перехода к отладчику используйте комбинацию клавиш Alt + F4. Список доступной отладочной информации можно получить нажав клавишу '?'. Однако, в справочную информацию вкралась ошибка - клавиша 2 показывает не список загруженных драйверов и протоколов, а дерево исполняемых процессов.
Спецификация интерфейсов задач Supervisor, FileSystem и спецификация интерфейсов драверов символьных и блочных устройств: xam_spec.pdf. Обратите внимание, данный документ имеет статус Draft.
Исходный код диспетчера сообщений задачи Supervisor: xam_dispatcher.cc (устаревшая версия).