Особенности загрузчика Linux
Во время загрузки Linux используют двоетапний загрузчика. Есть несколько программных продуктов, которые реализуют таких загрузчиков, самый известный из них lilo (от linux loader). Он может быть установлен как в МВR (заменив там код, который загружает первый сектор активного раздела), так и в загрузочном секторе какого-то (обычно активного) раздела диска. Второй подход является безопаснее при условиях, когда на компьютере установлено несколько ОС в режиме мультизагрузки, поскольку некоторые ОС могут перезаписывать МВR по своей инициативе.
Первая часть lilo, записанная в загрузочный сектор или МВR, во время своего выполнения готовит память и загружает у нее вторую часть. Но считывает из диска двоичное отображение карты имеющихся на компьютере вариантов загрузки (разные ОС, разные установки Linux и тому подобное) и предлагает пользователю выбрать один из них (с помощью подсказки «LILO boot.:»). Отметим, что исходную версию карты вариантов загрузки создает пользователь (системный администратор) в виде обычного текстового файла /etc/lilo.соnf. После каждого изменения карты необходимо обновлять ее отображение на диске, используемое загрузчиком. Для этого выполняют команду (с правами rооt):
# lilo
После выбора пользователем одного из вариантов загрузки поведение загрузчика зависит от характера файловой системы для раздела. В случае выбора раздела с другой ОС (например, Windows) считывают в память и выполняют загрузочный сектор этого раздела (потому с помощью liloможно загрузить любую ОС), если же выбран раздел из Linux, в память загружают ядро системы (его адрес на диске содержится в карте вариантов загрузки). После загрузки в памяти появляется сжатое ядро системы и пригодный для выполнения код двух функций загрузки:setup() I startup_32(). Код загрузчика переходит к выполнению функции setup(), начиная инициализацию ядра.
Инициализация ядра
Первый этап инициализации ядра происходит в реальном режиме процессора. Преимущественно осуществляется инициализация аппаратных устройств (Linux не доверяет этого ВIOS). Функция setup() определяет физический объем памяти в системе, будет инициализировать клавиатуру, видеокарту, контролер жесткого диска, некоторые другие устройства, переназначает таблицу прерываний, переводит процессор в защищенный режим и передает управление функции startup_32(), код которой также находится вне сжатого ядра.
Функция startup_32() задает сегментные регистры и стек, распаковывает образ ядра и располагает его в памяти. Дальше выполняют код распакованного ядра, при этом управление сначала достает функция, которую также называют startup_32(). Она формирует среду выполнения для первого потока ядра Linux («процесс 0»), создает его стек (из этого момента считают, что он есть), включает поддержку страничной организации памяти, задает начальные (пустые) обработчики прерываний, определяет модель процессора и переходит к выполнению функции start_kernel ().
Функцию start_kernel () выполняют в пределах потока ядра «процесс 0», завершая инициализацию ядра. Она доводит до рабочего состояния практически каждый компонент ядра, в частности:
· будет инициализировать таблицы страниц и все дескрипторы страниц;
· окончательно будет инициализировать таблицу прерываний;
· будет инициализировать кусковой распределитель памяти;
· устанавливает системные дату и время;
· выполняет код инициализации драйверов устройств;
· делает доступной корневую файловую систему (где расположены файлы, необходимые для загрузки системы).
Кроме того, с помощью функции kernel_thread() создают поток инициализации («процесс 1»), которая выполняет код функции init(). Этот поток создает другие потоки ядра и выполняет программу /shin/init, превращаясь в первый в системе процесс пользователя initи. Отметим, что для корректной загрузки initдолжна быть доступная корневая файловая система с важнейшими роздилюваними библиотеками (каталог /libдолжен быть на том же разделе, что и корневой каталог /).
На превращении этого потока в ипии инициализация ядра завершена, функция start_kernet () переходит в бесконечный цикл простоя (idle loop), не занимая ресурсов процессора. Последующая инициализация системы происходит во время выполнения init.
Загрузка Windows ХР
Загрузки Windows ХР начинают стандартным способом — из передачи управления коду загрузочного сектора активного раздела диска. Главное его задание — определить местонахождение файла ntldr в корневом каталоге этого раздела, загрузить его в память и передать управление на его точку входа. Отметим, что код загрузочного сектора зависит от того, какая файловая система установлена для этого раздела: для Fат выполняют один вариант, для NTFS — другой.
Файл ntldrможно рассматривать как загрузчик второго этапа. Он начинает свое выполнение в 16-битному режиме процессора, прежде всего переводит процессор в защищенный режим и включает поддержку страничной организации памяти, после этого считывает из корневого каталога файл boot.иnии делает его синтаксический разбор. Вот фрагмент файла boot.иnи:
[boot loader]
timeout=30
default=multi(0) disk(0) rdisk(0) partition(1)\WINDOWS
[operating systems]
multi (0) disk(0) rdisk(0) partition(1)\WINDOWS=Windows XP"
С:\="windows 98"
После тэгу [boot loader] задан вариант загрузки за умалчиванием и время, по завершении йкого система автоматически будет загружаться в соответствии с этим вариантом, после [орегаting systems] - список возможных вариантов загрузки. Для каждого варианта может быть задано один из нескольких адресов загрузки:
В раздел с корневым каталогом WINDOWS (для загрузки Windows ХР);
· литерное обозначение потому, на котором находится другая ОС;
· имя файла с указанием потому.
В случае указания литерного имени раздела (как в примере) ntidrнаходит на диске файл bootsec.dos (в котором после установления Windows ХР хранят загрузочный сектор DOS или Consumer Windows, если этаж его записан загрузочный сектор Windows ХР), переключает процессор в реальный режим и начинает выполнять код этого загрузочного сектора.
Если задано имя файла, ntldrбудет загружать файл с таким именем; следовательно, если в файле сохранить загрузочный сектор другой ОС, например, Linux, ntldrсможет загрузить и его, для этого вариант загрузки имеет такой вид:
С: bootsес. lnx="linux"
Дальше наведем случай загрузки Windows ХР. Отметим, что раздел с установкой Windows ХР в boot.ini не обязанный совпадать с разделом, из которого происходит загрузка, — таких разделов может быть несколько.
Когда есть один вариант загрузки, система сразу начинает загружаться, когда их больше — отображают меню загрузки. После выбора варианта из меню ntldrзапускает программу ntdetect.com, что в реальном режиме определяет базовую конфигурацию компьютера (подобно тому, как это делала функция setup() для Linux — ни одна из современных систем не доверяет этот код BIOS). Собранную информацию хранят в системе, позже она будет сохранена в реестре. Внизу экрана появляется текстовый индикатор прогресса. В этой ситуации можно нажать на F8и перейти в меню дополнительных возможностей загрузки (в безопасном режиме и тому подобное).
Потом ntldrзагружает в память ntoskrnl.ехе (что содержит ядро и исполнительную подсистему Windows ХР), bootvid.dll (видеодрайвер за умалчиванием, которое отвечает за отображение информации во время загрузки), hat.dll (уровень абстрагирования от оборудования) и основные файлы реестра. После этого он определяет из реестра, какие драйверы установлены в режиме запуска во время загрузки (это, например, драйвер жесткого диска) и загружает их (без инициализации). Будет загружен также драйвер корневой файловой системы. На этом роль ntldr в загрузке завершается, и он вызывает главную функцию в ntoskrnl.ехе для продолжения загрузки.
Инициализация ntoskrnl.ехесостоит из двух этапов: фаз 0и 1. Много подсистем исполнительной системы принимают параметр, который показывает, в какой фазе инициализации сейчас находится система.
Во время выполнения фазы 0прерывания запрещены, на экране ничего не отображается. Основной целью этого этапа является подготовка начальных структур данных, необходимых для расширенной инициализации во время выполнения фазы 1. Отметим, что менеджер процессов на этом этапе будет инициализироваться почти полностью, с его помощью создают начальный объект-процесс с названием Idle, процесс Systemи системный поток для выполнения инициализации фазы 1.
После завершения фазы 0прерывания разрешены, и начинает выполняться системный поток. Во время выполнения фазы 1управление экраном осуществляет видеодрайвер bootvid.dll, что отображает загрузочный экран и графический индикатор прогресса на нем (этот индикатор будет изменяться на протяжении всей фазы 1). Происходит окончательная инициализация разных подсистем исполнительной системы (менеджера объектов, планировщика, службы безопасности, менеджера виртуальной памяти, менеджера кэша и тому подобное). Во время инициализации подсистемы ввода-вывода (которая занимает до 50 % времени этой фазы) происходит подготовка необходимых структур данных, инициализация драйверов с запуском во время загрузки (boot-start), загрузки и инициализация драйверов с системным запуском (system-start). Фаза 1завершается запуском менеджера сессий (smss.ехе).
Последующую загрузку выполняют три системных процесса, рассмотренного в разделе 2: менеджер сессий smss.ехе, процесс регистрации в системе winiogon.ехеи менеджер управления сервисами (SCM, services.ехе). Основным заданием менеджера сессий является загрузка и инициализация всех компонентов подсистемы Win32 (как режиму пользователя, так и режиму ядра), а также окончательная инициализация реестра и запуск winiogon.ехе.
Процесс регистрации в системе запускает менеджер управления сервисами и менеджер аутентификации, а также организует регистрацию пользователей в системе.
Менеджер сервисов (SСМ) загружает и будет инициализировать сервисы режима пользователя, установленные в режиме автоматической загрузки. Этот процесс может длиться уже после начала интерактивной работы пользователей. После инициализации сервисов загрузки считают успешным.
Выводы
· Ни одна операционная система не может начать работу без выполнения процедуры загрузки и инициализации. Во время этого процесса сначала выполняется самый простой загрузчик ОС, которая находится в фиксированном месте жесткого диска, потом он отыскивает ядро ОС и загружает его в память. Ядро в свою очередь будет инициализировать свои внутренние структуры и аппаратное обеспечение и передает управление процессам пользователя или системным процессам, которые завершают процесс инициализации.
· Широко распространенна двухэтапная загрузка, во время которой загрузчик ОС передает управление более сложному загрузчику второго этапа, который может руководить загрузкам нескольких систем, установленных на компьютере. Такой загрузчик выполняет основные действия относительно взаимодействия с пользователем и загрузки нужной системы.
Контрольные вопросы и задания
1. Какие дополнительные возможности администрирования предоставляют ОС, у которых есть поддержка загрузки ядра системы из флоппи-диска?
2. Укажите преимущества установления загрузчика системы в МВR сравнительно с его установлением в загрузочный сектор одного из разделов диска.
3. Компьютерная Система включает несколько НЖМД, на каждом из которых установлена своя файловая система. Опишите, в какой последовательности эти системы должны быть смонтированные во время загрузки. Есть ли необходимость в ходе загрузки получать доступ к диску без использования средств ядра?
4. Идентификатор процесса для init равняется единице, он меньше, чем у любого потока ядра Linux. В то же время init становится процессом позже, чем будут созданы потоки ядра. Как можно это объяснить?
5. Альтернативным способом загрузки ОС является подход, реализованный для Linux утилитой loadlin. Эта утилита выполнялась под управлением МS-DOS или Windows и загружала ядро Linux из файловой системы FАТ. После загрузки ядра в память последующий процесс шел, как описано в разделе 9.2.(Л2) Назовите преимущества и недостатки такого подхода.