Введение
Операционная система реального времени
DNIX (оригинальное написание: D Nix) – это прекращенная разработка Unix-подобной операционной системы реального времени от шведской компании Dataindustrier AB (DIAB). Версия под названием ABCenix была разработана для компьютера ABC 1600 производства Luxor. Daisy Systems также имела систему Daisy DNIX на некоторых своих рабочих станциях автоматизированного проектирования (CAD). Она не имела отношения к продукту DIAB.
Начало в DIAB в Швеции
Dataindustrier AB (буквальный перевод: акционерная компания компьютерных индустрий) была основана в 1970 году Ларсом Карлссоном как производитель одноплатных компьютеров в Сундсвалле, Швеция, выпускавший компьютер на базе Zilog Z80 под названием Data Board 4680. В 1978 году DIAB начала сотрудничество со шведской телевизионной компанией Luxor AB для производства серий домашних и офисных компьютеров ABC 80 и ABC 800. В 1983 году DIAB самостоятельно разработала первую машину, совместимую с Unix, DIAB DS90, основанную на процессоре Motorola 68000. D NIX появилась на основе лицензии UNIX System V от корпорации AT&T. Однако DIAB являлась компанией, специализирующейся на системах промышленного управления (автоматизации), и нуждалась в операционной системе реального времени, поэтому компания заменила ядро UNIX, поставляемое AT&T, на собственную разработанную, но совместимую версию для реального времени. Это ядро было вдохновлено ядром Z80 под названием OS.8, созданным для подразделения Monroe Systems компании Litton Industries. Со временем компания также заменила ряд стандартных утилит пользовательского пространства UNIX собственными реализациями, вплоть до того, что ни один код не был получен из UNIX, и их машины могли быть развернуты независимо от какой-либо лицензии AT&T UNIX. Через два года, в сотрудничестве с Luxor, был разработан компьютер ABC 1600 для офисного рынка, а параллельно DIAB продолжала производить улучшенные версии компьютера DS90, используя более новые версии процессоров Motorola, такие как Motorola 68010, 68020, 68030 и, в конечном итоге, 68040. В 1990 году DIAB была приобретена Groupe Bull, которая продолжила производство и поддержку машин DS под брендом DIAB, с такими названиями, как DIAB 2320, DIAB 2340 и т.д., работающих на версии DIAB DNIX.
Деривативные инструменты в ISC Systems Corporation
ISC Systems Corporation (ISC) приобрела право использования DNIX в конце 1980-х годов для использования в своей линейке банковских компьютеров на базе Motorola 68k. (Позже ISC была приобретена Olivetti, а затем перепродана Wang, которая, в свою очередь, была куплена Getronics. Эта корпорация, чаще всего называемая «ISC», на протяжении многих лет имела множество различных названий.) Эта ветвь кода была совместима с SVR2 и подверглась значительной модификации и доработке. К заметным особенностям этой операционной системы относились поддержка страничной организации памяти, бездисковых рабочих станций, многопроцессорности, асинхронного ввода/вывода (I/O), возможность монтирования процессов (обработчиков) в каталоги файловой системы и передача сообщений. Поддержка работы в реальном времени в основном основывалась на внутренних очередях, управляемых событиями, а не на механизмах поиска по списку (отсутствие эффекта «греющегося стада»), статических приоритетах процессов двух классов (выполнение до завершения и разделение по времени), поддержке смежных файлов (для предотвращения фрагментации критически важных ресурсов) и блокировке памяти. Качество реализации ортогональных асинхронных событий до сих пор не было превзойдено в современных коммерческих операционных системах, хотя некоторые из них к этому приближаются. (Концепция, которая пока не получила распространения, заключается в том, что синхронная точка обработки всей асинхронной активности также может быть асинхронной, и так до бесконечности. DNIX справилась с этим блестяще.) Асинхронный ввод/вывод устранял необходимость использования select из библиотеки Berkeley sockets или механизма опроса STREAMS в SVR4, хотя существовала библиотека эмуляции сокетов, сохранявшая семантику сокетов для обратной совместимости. Еще одной особенностью DNIX было то, что ни одна из стандартных утилит (например, ps, часто злоупотребляющая этим) не просматривала память ядра для выполнения своей работы. Вместо этого использовались системные вызовы, что позволяло свободно изменять внутреннюю архитектуру ядра по мере необходимости. Концепция обработчика позволяла размещать стеки сетевых протоколов вне ядра, что значительно упрощало разработку и повышало общую надежность, хотя и за счет производительности. Это также позволило реализовать иностранные файловые системы в виде процессов пользовательского уровня, опять же для повышения надежности. Основная файловая система, хотя и могла быть (и когда-то была) внешним процессом, была перенесена в ядро из соображений производительности. Если бы этого не произошло, DNIX вполне могла бы считаться микроядром, хотя формально она как таковая не разрабатывалась. Обработчики могли представляться как любой тип «родного» Unix-файла, структуры каталогов или устройства, а запросы ввода/вывода файлов, которые обработчик не мог обработать, могли передаваться другим обработчикам, включая базовый, на котором был смонтирован обработчик. Соединения между обработчиками также могли существовать и передаваться независимо от файловой системы, подобно каналу. Одним из следствий этого является то, что устройства, подобные текстовым терминалам (TTY), можно было эмулировать без необходимости использования псевдотерминала на основе ядра. Примером того, как обработчик спас ситуацию, была поддержка бездисковых рабочих станций ISC, где ошибка в реализации приводила к тому, что использование именованных каналов на рабочей станции могло вызвать нежелательную блокировку ресурсов на файловом сервере. На рабочей станции был создан обработчик для перехвата доступа к проблемным именованным каналам до разработки соответствующих исправлений ядра. Для реализации этого обработчика требовалось около 5 килобайт кода, что указывает на то, что нетривиальный обработчик не обязательно должен быть большим. ISC также получила право производить машины DIAB DS90 10 и DS90 20 в качестве файловых серверов. Многопроцессорные DS90 20 были слишком дорогими для целевого рынка, поэтому ISC разработала собственные серверы и портировала на них DNIX. ISC разработала собственные GUI-основанные бездисковые рабочие станции для использования с этими файловыми серверами и снова портировала DNIX. (Хотя ISC использовала рабочие станции Daisy, работающие под управлением Daisy DNIX, для проектирования машин, которые должны были работать под управлением DNIX DIAB, внутри компании было мало путаницы, поскольку сотрудники, занимающиеся проектированием и макетом, редко общались с сотрудниками, занимающимися разработкой программного обеспечения. Более того, сотрудники, занимающиеся проектированием оборудования, не использовали ни одну из этих систем! В компании ходила шутка примерно такого содержания: «В ISC мы строим компьютеры, мы их не используем».) Поддержка асинхронного ввода/вывода в DNIX обеспечивала простое программирование, управляемое событиями, на рабочих станциях, которое работало хорошо, несмотря на относительно ограниченные ресурсы. (GUI-бездисковая рабочая станция имела процессор 68010 с частотой 7 МГц и могла использоваться только с 512 КБ памяти, из которых ядро потребляло примерно половину. Большинство рабочих станций имели 1 МБ памяти, хотя позже появились версии на 2 МБ и 4 МБ, а также процессоры с частотой 10 МГц.) Полная установка могла состоять из одного сервера (68020 с частотой 16 МГц, 8 МБ оперативной памяти и жесткий диск на 200 МБ) и до 64 рабочих станций. Хотя загрузка занимала много времени, такая конфигурация могла приемлемо работать в банковском приложении для кассиров. Помимо присущей DNIX эффективности, сопутствующий компилятор DIAB C был ключевым фактором высокой производительности. Он генерировал особенно хороший код для 68010, особенно после того, как ISC его доработала. (ISC также перенацелила его на графический сопроцессор Texas Instruments TMS34010, использовавшийся в ее последней рабочей станции.) Компилятор DIAB C, конечно же, использовался для сборки DNIX, что было одним из факторов, способствующих его эффективности, и он до сих пор доступен в той или иной форме через Wind River Systems. Эти системы до сих пор используются по состоянию на 2006 год в бывших отделениях Seattle First National Bank, которые теперь носят бренд Bank of America. Вероятно, есть и другие клиенты ISC, которые до сих пор используют DNIX в той или иной степени. Благодаря ISC существовало значительное присутствие DNIX в Центральной и Южной Америке.
Совместимость
В дополнение к нативному системному вызову dnix(2) был доступен полный набор "стандартных" вызовов интерфейса libc: open(2), close(2), read(2), write(2) и т.д. Помимо обеспечения обратной совместимости, эти вызовы были реализованы таким образом, чтобы быть двоично совместимыми с компьютером NCR Tower, что позволяло бинарным файлам, скомпилированным для него, работать без изменений в DNIX. Ядро DNIX имело два внутренних диспетчера прерываний, один для метода DNIX и один для метода Unix. Выбор диспетчера зависел от программиста, и их взаимозаменяемое использование было допустимо. Семантически они были идентичны там, где функциональность совпадала. (На этих машинах для вызовов unix(2) использовалась инструкция 68000 trap #0, а для dnix(2) – инструкция trap #4. Оба обработчика прерываний были очень похожи, хотя вызов unix(2) хранил код функции в регистре D0 процессора, а dnix(2) – на стеке вместе с остальными параметрами.) DNIX 5.2 не содержал встроенных стеков сетевых протоколов (за исключением упрощенного стека протоколов Ethernet на основе X.25, добавленного ISC для поддержки его бездисковых рабочих станций). Вся сетевая коммуникация осуществлялась посредством чтения и записи в обработчики. Таким образом, механизма сокетов не было, но существовала libsocket(3), которая использовала асинхронный ввод-вывод для взаимодействия с обработчиком TCP/IP. Типичная сетевая программа, производная от Berkeley, могла быть скомпилирована и запущена без изменений (с учетом обычных проблем портирования Unix), хотя она могла быть менее эффективной, чем эквивалентная программа, использующая нативный асинхронный ввод-вывод.
Расширения ISC
ISC приобрела как версии 5.2 (совместимые с SVR2), так и версии 5.3 (совместимые с SVR3) DNIX. На момент покупки DNIX 5.3 все еще находилась в разработке в DIAB, поэтому была развернута DNIX 5.2. Со временем инженеры ISC включили большинство функций своего ядра 5.3 в 5.2, в первую очередь общую память и межпроцессное взаимодействие (IPC), поэтому между версиями DIAB и ISC DNIX возникло некоторое расхождение в функциональности. DIAB 5.3, вероятно, содержала больше функций SVR3, чем ISC 5.2. Кроме того, DIAB перешла на DNIX 5.4, операционную систему, совместимую с SVR4. На ISC разработчики значительно расширили свою версию DNIX 5.2 (в списке указаны только функции, связанные с ядром), основываясь как на своих потребностях, так и на общих тенденциях в индустрии Unix:
Поддержка бездисковых рабочих станций. Файловая система ядра рабочей станции была удалена и заменена на коммуникационный модуль на основе X.25 и Ethernet. Ядро файлового сервера также было расширено компонентом, принимающим удаленные запросы и передающим их в пул процессов ядра для обработки, хотя для этого можно было написать стандартный обработчик. (Позже, в течение жизненного цикла продукта, ISC развернула стандартные Unix-серверы на основе SVR4 вместо серверов DNIX. Они использовали X.25 STREAMS и специально разработанную программу файлового сервера. Несмотря на менее эффективную структуру, вычислительная мощность используемых платформ обеспечивала значительно более высокую скорость работы сервера. К сожалению, эта программа файлового сервера не поддерживала всю функциональность нативного сервера DNIX. Некоторые сложные вещи, такие как именованные каналы, вообще не работали. Это было еще одним обоснованием для процесса обработки именованных каналов.) Поддержка точек останова gdb с использованием возможностей MMU ISC. Асинхронный ввод-вывод в файловую систему был реализован. (Изначально он все равно блокировался.) Для этого использовались процессы ядра (kprocs или потоки). Поддержка программы, аналогичной truss или strace. В дополнение к исправлениям ошибок в стандартном механизме пошагового выполнения ptrace Unix, потребовалось добавить временный механизм усыновления процессов, чтобы трассировщик мог использовать стандартный механизм пошагового выполнения для существующих процессов. Расширения механизма сигналов SVR4. В основном для новых сигналов STOP и CONT, но также включающие новые вызовы управления сигналами. Из-за отсутствия исходного кода отладчиков adb и sdb у ISC страницу u нельзя было изменить, поэтому новые сигналы можно было только блокировать или обрабатывать по умолчанию, их нельзя было перехватывать. Поддержка анализа сетевого трафика. Это потребовало расширения драйвера Ethernet, чтобы одно событие могло удовлетворить более одного запроса ввода-вывода, и условной реализации аппаратной фильтрации в программном обеспечении для поддержки режима promiscuous. Зеркалирование дисков. Это было реализовано в файловой системе, а не в драйвере устройства, чтобы слегка (или даже полностью) разные устройства все еще могли быть зеркалированы вместе. Зеркалирование небольшого жесткого диска на дискету было популярным способом тестирования зеркального отображения, поскольку извлечение дискеты было простым способом вызвать ошибки диска. 32-битный индексный дескриптор (inode), имя файла длиной 30 символов, символические ссылки и расширения "липкой" директории в файловой системе. Добавлены устройства /dev/zero, /dev/noise, /dev/stdXXX и /dev/fd/X. Списки идентификаторов групп процессов (из SVR4). Прямое исполнение скриптов с помощью #!. Умножение последовательных портов с использованием коммуникационных плат VMEbus на базе Z 80 ISC. Перемещаемый раздел подкачки. Снимки состояния ("дампы") работающих процессов. Поддержка команды fuser. Функция изменения приоритета процесса (renice). Связанная программа переприоритизации для реализации плавающих приоритетов. Способ "лишить" процесс, мгновенно лишив его всех ресурсов памяти. Очень полезно для определения текущего рабочего набора, в отличие от того, что все еще доступно, но не обязательно используется. Это было связано с графической утилитой, отображающей статус всех 1024 страниц карты памяти процесса. (Это количество страниц памяти, поддерживаемых MMU ISC.) В процессе использования вы периодически "лишали" целевой процесс в течение его жизни, а затем наблюдали, сколько памяти было возвращено обратно. Это было полезно, поскольку производственная среда ISC использовала только несколько долгоживущих процессов, контроль их использования памяти и роста был ключевым фактором для поддержания производительности.