Купить недорого оригинальные часы в самаре bestclock63.ru.

Компоненты ОС

Наряду с двумя перечисленными на прошлой странице точками зрения существует и третья. Формулировки ее в явном виде мне не встречалось (хотя в виде неявном, то есть на практике, ее придерживаются разработчики систем BSD-клана). И потому возьму на себя смелость такую формулировку дать:

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

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

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

В функции ядра большинства POSIX-систем входят: распределение процессорного времени между задачами, управление памятью -- как физической, так и виртуальной (то есть процессом своппинга), взаимодействие с устройствами, доступ к файловым системам, обеспечение ввода/вывода данных, сетевая поддержка.

От всех остальных программ ядро отличается двумя важными особенностями. Во-первых, оно функционирует в отдельной области памяти, которая так и называется пространством ядра (kernelland во FreeBSD). И в которую пользовательские процессы доступа не имеют -- обращаться, скажем, к устройствам ввода/вывода они должны посредством процедуры системных вызовов к соответствующим подсистемам ядра. Все прочие же программы располагаются в так называемом пользовательском пространстве памяти (userland).

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

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

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

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

Соответственно этому, ядра могут быть разделены на монолитные (со встроенной поддержкой всего, чего нужно), и модульные. Впрочем, разделение это -- чисто теоретическое: во всех ядрах, в принципе поддерживающих модули (а это -- и Linux, и все BSD-системы), они в том или ином объеме используются. Чисто монолитные ядра имеют смысл только для каких-то специальных задач.

Следующий шаг в том же направлении -- так называемые микроядра, представителем которых является Mach и L4 (последнее ныне используется в Hurd). Их отличие -- в том, что "опциональные" фрагменты кода, например, драйверы устройств, не просто вынесены в отдельные модули, но и функционируют в пользовательском пространстве памяти. А собственно за ядром оставлены функции коммуникаций между ними.

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

Так что до сих пор пример успешной реализации микроядерной архитектуры был один -- узкоспециализированная ОС QNX (поминаемая в этой связи MacOS X является микроядерной скорее по названию, чем по сути). Возможно, что развитие MINIX3 изменит это положение.

В последнее время многие идеи, идущие от проекта Mach, были реализованы в ядре DragonFlyBSD -- ответвлении FreeBSD, ориентированном на работу в многопроцессорных системах. Хотя в собственном смысле слова к микроядерным её тоже отнести нельзя.

Очевидно, что для работы ядро необходимо тем или иным способом загрузить. Что, как будет показано со временем, оно в принципе способно проделать собственными силами -- то есть теоретически загрузчик не кажется неотъемлемой частью операционной системы. Однако практически "самозагрузка" ядра настолько неудобна (и не всегда приемлема), что на самом деле без загрузчика не обойтись.

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

Далее следуют утилиты поддержки функций ядра, обеспечивающие работу с устройствами, файловыми системами, сетевыми протоколами. Согласитесь, мало радости пользователю от поддержки ядром некоей файловой системы, если он не располагает инструментами для работы с ней. А отсюда -- третий непременный компонент операционки, включающий средства обращения к физическим носителям, создания на них разделов, логических томов и файловых систем, их проверки, монтирования и т.д. Если же ядро предусматривает поддержку нескольких файловых систем (как это имеет быть, например, для ядра Linux) в качестве родных (native) -- к каждой из них должен прилагаться свой комплекс обслуживающих утилит. При этом следует помнить, что многие функции ядра могут быть реализованы как модули, и поэтому средства управления оными -- загрузки, выгрузки, получения информации, -- также должны быть включены в эту группу.

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

Для своего функционирования как ядро, так и системные и пользовательские утилиты нуждаются в так называемых системных библиотеках. Из них главной оказывается libc -- библиотека функций языка Си (главного средства разработки в контексте UNIX-систем). Однако не менее важны и некоторые другие библиотеки, например, например, свойств терминала. Это -- своего рода средства тылового обеспечения, практически незаметные пользователю, но, тем не менее, незаменимые. И потому они являют собой пятый обязательный компонент ОС.

Любые действия в любой системе выполняются, прямо или косвенно, путем отдачи соответствующих командных директив. И потому интегрирующей надстройкой над всем описанным богачеством выступает командная оболочка, она же -- интерпретатор языка команд, или, по простому -- шелл (shell). Это -- шестой компонент ОС, роль которого невозможно переоценить: со временем мы увидим, что и система инициализации -- лишь набор сценариев оболочки, и всякого рода приложения с навороченными интерфейсами -- лишь надстройки над элементарными шелл-командами и их комбинациями.

И, наконец, последний, седьмой, из необходимых компонентов ОС -- внутренняя система документации, дающая пользователю возможность изучения возможностей системы. Таковой испокон веков в UNIX выступает система man-страниц (Manual Pages). Не смотря на появление множества других форматов для представления документов, при всей своей архаичности остающаяся простым и универсальным средством оперативного получения исчерпывающей справочной информации.

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

Первый -- средства наращивания системы дополнительными программами, то есть комплекс инструментов, объединяемых понятием пакетного менеджмента: установки пакетов, отслеживания и удовлетворения зависимостей между ними, а также удаления. Эти действия могут выполняться вручную -- посредством простой сборки программ из исходных текстов. И это универсальный метод, применимый в любой UNIX-подобной системе. В этом случае достаточно наличия компилятора для языка Си/Си++ и сопутствующего инструментария (линкера, ассемблера, средств ведения проекта). В FOSS-системах такой инструментарий практически безальтернативен, включая пакеты gcc (компилятор) и binutils с сопутствующими утилитами типа make, automake, autoconfig. Каковые и могут быть включены в операционную систему в качестве восьмого, но уже необязательного, компонента.

Второй метод установки программ -- компиляция их из исходников по определенным правилам, освобождающим пользователя от необходимости самому отслеживать и удовлетворять зависимости. В этом случае компилятора и сопутствующего инструментария оказывается недостаточно -- требуется еще и система автоматизации сборки. Таковая впервые появилась во FreeBSD под названием системы портов, и в дальнейшем ее аналоги широко распространились как в BSD-мире, так и в многих разновидностях Linux.

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

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

И последний из дополнительных (но опять-таки практически необходимых) компонентов ОС -- средства для обеспечения работы в графическом режиме. Сам по себе UNIX и все его потомки и производные таковых внутри себя не имели и не имеют. Эта функция возлагается на кросс-платформенную систему -- X Window System, именуемую также оконной системой X или, в народе, просто Иксами. Изначально не привязанная ни к аппаратной архитектуре, ни к какой-либо ОС, сама по себе она не имеет отношения ни к одному из дистрибутивов Linux, ни к BSD-семейству ОС, ни даже к UNIX вообще. Да и стандарты POSIX как-будто бы ничего о ней не говорят -- реализации Иксов регламентируются собственными стандартами, разрабатываемыми специальной организацией -- X-консорциумом (X Consorcium).

Тем не менее, Иксы в их свободной реализации для Intel-совместимых процессоров, оказываются непременной частью всех открытых и свободных POSIX-систем -- и любого дистрибутива Linux, и Solaris, и всех BSD-клонов. Более того, реализация эта ныне безальтернативна и представлена Xorg -- составной частью проекта Freedesktop.org: исполнявший ранее эту роль проект XFree86 практически никем уже не поддерживается, а разнообразные коммерческие X-сервера своё давно отжили. Так что иного общепринятого и универсального способа доступа к графическим возможностям PC просто нет.

Иксы лежат как бы на грани между базовым комплектом рассматриваемых операционных систем и их обрамлением, выступая по отношению к приложениям графического режима примерно в том же качества, что и базовые компоненты операционки -- по отношению к утилитам и приложениям режима текстового. И об этом всегда нужно помнить. Как, впрочем, и о том, что Иксы -- это не Linux, не FreeBSD, не Solaris, и не какая-либо другая ОС: это общее достояние всех UNIX-подобных операционок.

Однако и Иксы оказываются не последним из необязательных компонентов. И сами по себе в "голом" виде, не способны выполнять какие-либо практические задачи. Для этого требуются специальные рабочие среды, именуемые менеджерами окон или интегрированными десктопами. Которые, в свою очередь, функционировать без Иксов не могут, так что оторвать их друг от друга невозможно.

И что мы получаем, если соберем вместе все перечисленное выше, оставив временно за кадром средства обеспечения графического режима? А получаем мы практически то, что во FreeBSD охватывается понятием Distributions, вернее, той его частью, которая именуется Base и является единственным компонентом, обязательным при минимальной установке. Аналогичный базовый комплекс программ (так и называемый -- Base) есть также в NetBSD и OpenBSD. Причем, если ядра в этих системах и различны, то программы системного обрамления -- чрезвычайно близки (местами до полной идентичности).

В Linux'е вычленить нечто подобное из какого-либо многодискового дистрибутива Linux'а несколько сложнее. Однако, напротив, можно прикрутить к его ядру некое подобие такой самодостаточной целостности. По аналогии с BSD ее можно назвать Base Linux -- именно этот термин использовал в своё время автор этих строк в соответствующей статье.

Ещё сложнее дело обстоит в Solaris. Исторически в этой системе существовал собственный комплекс системных и пользовательских утилит обрамления, частично унаследованный от ранних BSD. Ныне же, по крайней мере в свободной её инкарнации (OpenSolaris -- а только о ней и её свободных дериватах и будет говориться в этой книге), пользовательские утилиты представлены своими GNU-реализациями -- точно теми же, что и в Linux. Хотя системное окружение непосредственной поддержки функций ядра, естественно, осталось ОС-специфическим. И, как я уже писал на предыдущей странице, в понятие OS Solaris включаются также средства обеспечения работы в графическом режиме, то есть Иксы и рабочая среда. Что оправданно не только исторически: в реализации Solaris для Sparc-архитектур, в силу аппаратных особенностей платформы, настоящего текстового режима просто нет, а в реализации для x86 -- он носит рудиментарный характер.

Подведем итог столь длительных рассуждений. В состав любой POSIX-совместимой системы входит базовый набор из семи обязательных компонентов:

  1. ядро ОС;
  2. средства загрузки и инициализации системы;
  3. системные утилиты, обеспечивающие исполнение ядром его функций;
  4. средства "боевого обеспечения" -- минимальный набор пользовательских утилит;
  5. средства "тылового обеспечения" -- системные библиотеки;
  6. командная оболочка;
  7. система документации.

Они дополняются двумя как бы опциональными (но практически столь же обязательными компонентами): той или иной системой управления пакетами и системой поддержки работы в графическом режиме. Хотя, например, встраиваемые системы или системы управления процессами могут прекрасно обойтись и без того, и без другого.


Теги: