Архитектура Unix

       

. Алгоритм загрузки системы



Рисунок 7.30. Алгоритм загрузки системы

алгоритм start /* процедура начальной загрузки системы */ входная информация: отсутствует выходная информация: отсутствует { проинициализировать все структуры данных ядра; псевдо-монтирование корня; сформировать среду выполнения процесса 0; создать процесс 1; { /* процесс 1 */ выделить область; подключить область к адресному пространству процесса init; увеличить размер области для копирования в нее ис- полняемого кода; скопировать из пространства ядра в адресное прост- ранство процесса код программы, исполняемой процес- сом; изменить режим выполнения: вернуться из режима ядра в режим задачи; /* процесс init далее выполняется самостоятельно -- * в результате выхода в режим задачи, * init исполняет файл "/etc/init" и становится * "обычным" пользовательским процессом, производя- * щим обращения к системным функциям */ } /* продолжение нулевого процесса */ породить процессы ядра; /* нулевой процесс запускает программу подкачки, управ- * ляющую распределением адресного пространства процес- * сов между основной памятью и устройствами выгрузки. * Это бесконечный цикл; нулевой процесс обычно приоста- * навливает свою работу, если необходимости в нем боль- * ше нет. */ исполнить программу, реализующую алгоритм подкачки; }


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

Процесс init (Рисунок 7.31) выступает диспетчером процессов, который порождает процессы, среди всего прочего позволяющие пользователю регистрироваться в системе. Инструкции о том, какие процессы нужно создать, считываются процессом init из файла "/etc/inittab". Строки файла включают в себя идентификатор состояния "id" (однопользовательский режим, многопользовательский и т. д.), предпринимаемое действие (см. упражнение 7.43) и спецификацию программы, реализующей это действие (см. Рисунок 7.32). Процесс init просматривает строки файла до тех пор, пока не обнаружит идентификатор состояния, соответствующего тому состоянию, в котором находится процесс, и создает процесс, исполняющий программу с указанной спецификацией. Например, при запуске в многопользовательском режиме (состояние 2) процесс init обычно порождает getty-процессы, управляющие функционированием терминальных линий, входящих в состав системы. Если регистрация пользователя прошла успешно, getty-процесс, пройдя через процедуру login, запускает на исполнение регистрационный shell (см. главу 10). Тем временем процесс init находится в состоянии ожидания (wait), наблюдая за прекращением существования своих потомков, а также "внучатых" процессов, оставшихся "сиротами" после гибели своих родителей.

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

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



Содержание раздела