Меню
Главная
Случайная статья
Настройки
|
Процесс загрузки Linux — последовательность действий, посредством которых приводятся в состояние готовности операционные системы на основе Linux. Этот процесс во многом схож с загрузкой BSD и других Unix-подобных систем, от которых он и происходит.
Содержание
Общий обзор процесса
При загрузке компьютера происходит последовательная передача управления от системной прошивки компьютера (BIOS или UEFI) к загрузчику, а от него — к ядру. Затем ядро запускает планировщик (для реализации многозадачности) и выполняет программу init (которая настраивает пользовательское окружение и позволяет осуществлять взаимодействие с пользователем и вход в систему), после чего ядро переходит в состояние бездействия до тех пор, пока не получит внешний вызов.
Основные этапы загрузки:
- Системная прошивка компьютера выполняет первичную проверку и инициализацию аппаратного обеспечения.
- В случае BIOS прошивка загружает в оперативную память и выполняет загрузочный код с одного из разделов заданного загрузочного устройства, который содержит фазу 1 загрузчика Linux. Фаза 1 загружает фазу 2 (значительный по размеру код загрузчика). Некоторые загрузчики могут использовать для этого промежуточный этап (под названием фаза 1,5), поскольку современные диски большого объёма могут некорректно считываться без дальнейшего кода. В случае UEFI запускается загрузчик загруженный со служебного раздела (EFS), который выбирается согласно настройкам приоритета загрузки определенного в энергонезависимой памяти компьютера. При этом возможна загрузка не только специализированного загрузчика, но можно загрузить и непосредственно ядро Linux (для этого ядро должно быть собрано с опцией EFI_STUB).
- Загрузчик зачастую предлагает пользователю меню с доступными вариантами загрузки. После выбора или после заданного тайм-аута загрузчик загружает ядро.
- Загруженное ядро распаковывается в памяти, настраивает системные функции, такие как работа необходимого оборудования и управление страницами памяти, после чего делает вызов
start_kernel() .
- После этого
start_kernel() выполняет основную настройку системы (прерывания, остальные функции управления памятью, инициализацию устройств, драйверов и т. д.), а потом порождает процесс бездействия, диспетчер и отдельно от них — процесс init (выполняющийся в пользовательском пространстве).
- Планировщик начинает более эффективно управлять системой, в то время как ядро переходит к бездействию.
- Процесс init выполняет необходимые сценарии, которые настраивают все службы и структуры, не относящиеся к уровню ядра, в результате чего будет создано пользовательское окружение, и пользователю будет предоставлен экран входа в систему.
Когда происходит завершение работы, init вызывается для управляемого закрытия программ пользовательского уровня, тоже согласно сценариям. После этого init закрывается, а ядро производит своё собственное завершение работы.
Фаза загрузчика
При загрузкe через BIOS: Фазы загрузчика различаются в зависимости от платформы. Поскольку ранние этапы загрузки не зависят от операционной системы, процесс загрузки обычно начинается следующим образом:
- Для x86 или x86-64: код с загрузочного сектора раздела диска выполняется в реальном режиме и загружает первую фазу загрузчика (как правило — часть LILO или GRUB).
С этого момента загрузка продолжается. Первая фаза загружает остальной код загрузчика, который обычно спрашивает, какую операционную систему (или вид её сессии) пользователь хочет запустить. Код загрузчика создаётся на основе конфигурационного файла /etc/lilo.conf (для LILO) , в котором определены доступные системы. Этот файл содержит, в частности, информацию о загрузочном разделе и расположении ядра для каждой из таких систем, а также дополнительные параметры загрузки, если они заданы. В результате выбора соответствующее ядро загружается в ОЗУ, минимальная начальная файловая система настраивается из файла-образа (initrd), а затем, вместе с соответствующими параметрами управление передаётся новой ОС.
LILO и GRUB имеют определённые различия:[1]
- LILO не распознаёт файловые системы, поэтому он использует непосредственные (raw) смещения на диске и сведения из BIOS для загрузки данных. Он загружает код меню, а потом, в зависимости от выбора, загружает либо 512-байтные секторы диска для системы, основывающейся на MBR (например, Microsoft Windows), либо образ ядра для Linux.[1]
- GRUB, наоборот, распознаёт распространённые файловые системы (например, ext2 и ext3).[2] Так как GRUB хранит свои данные в файле конфигурации, а не в загрузочной записи, и имеет интерфейс командной строки, то зачастую параметры GRUB легче поправить или изменить, если они настроены неправильно или повреждены.[3]
При загрузке через UEFI: В UEFI загрузчик сразу запускается в защищенном режиме (32- или 64-битном) и фактически загружаются сразу все фазы загрузчика (с учетом загрузки со служебного раздела для загрузчика нет необходимости разбивать себя на отдельные фазы и размещать их в разных местах). В остальном процесс загрузки и инициализации ядра не отличается от варианта с BIOS.
GRUB
BIOS:
- Загрузчик 1-й фазы считывается BIOS из MBR (главной загрузочной записи).[4]
- Он загружает оставшуюся часть загрузчика (2-ю фазу). Если вторая фаза находится на большом диске, иногда загружается промежуточная фаза 1,5, которая содержит дополнительный код, позволяющий считывать цилиндры с номерами более 1024 (диски LBA). Загрузчик фазы 1,5 хранится (если это необходимо) в MBR или в загрузочном разделе.[4]
- Выполняется вторая фаза загрузчика и отображает меню запуска GRUB. Оно также позволяет выбрать среду выполнения и просмотреть параметры системы.
- Когда операционная система выбрана, она загружается и ей передаётся управление.[4]
GRUB поддерживает и прямой, и цепной способ загрузки, а также LBA, ext2, и «истинно командно-ориентированную, дооперационную среду на машинах x86». Он имеет три интерфейса: меню выбора, редактор настроек и командную консоль.[4]
UEFI:
- Загруженный со служебного раздела EFS GRUB (специальная версия бинарного файла, который умеет загружать UEFI) содержит в себе все необходимые компоненты для доступа к файловой системе /boot где находятся конфигурация и дополнительные файлы загрузчика.
- Отображается меню загрузчика и отображает меню запуска GRUB. Оно также позволяет выбрать среду выполнения и просмотреть параметры системы.
- Когда операционная система выбрана, она загружается и ей передаётся управление.[4]
LILO
LILO старше GRUB и практически аналогичен ему в действии, за исключением того, что не содержит интерфейса командной строки. Поэтому все изменения нужно вносить в его настройки и записывать в MBR, после чего систему перезагружают. Таким образом, ошибка в настройках может сделать диск неспособным к загрузке без использования отдельного загрузочного устройства (дискеты и т. п.), содержащего программу для исправления ошибки.[3] Кроме того, LILO не распознаёт файловые системы; вместо этого, адреса файлов-образов хранятся непосредственно в MBR,[3] а BIOS используется для прямого к ним доступа.
Loadlin
Ещё один способ загрузить Linux — из DOS или Windows 9x, где ядро Linux полностью заменит выполняющуюся копию операционной системы. Это может быть целесообразно, если аппаратное обеспечение должно включаться программно, а соответствующие программы существуют только для DOS, а не для Linux, будучи проприетарным ПО производителя и объектом коммерческой тайны. Этот метод загрузки не особо актуален, так как в Linux есть драйверы для множества аппаратных устройств, хотя в прошлом он был весьма полезен.
Другой пример: когда Linux находится на устройстве хранения данных, которое не предназначено для загрузки из BIOS: DOS или Windows могут загрузить соответствующие драйверы, чтобы обойти такое ограничение BIOS, а затем загрузить оттуда Linux.
Фаза ядра
Ядро Linux управляет главными функциями, такими как управление памятью, диспетчер задач, ввод-вывод, межпроцессное взаимодействие и общее управление системой. Загрузка проходит в два этапа: на первом ядро (в виде сжатого файла-образа) загружается в оперативную память и распаковывается, далее настраиваются такие базовые функции, как основное управление памятью. Затем управление в последний раз передается основному процессу запуска ядра. Как только ядро становится полностью работоспособным (то есть загруженным и выполнившим свой код), оно находит и запускает процесс init, который самостоятельно настраивает пользовательское пространство и процессы, необходимые для функционирования пользовательского окружения и итогового входа в систему. Само ядро переходит в режим бездействия и готовности к вызовам со стороны других процессов.
Этап загрузки ядра
Ядро при загрузке обычно имеет вид файла-образа, сжатого в формат zImage или bzImage с помощью zlib. В нём содержится головная программа, которая проводит минимальную настройку оборудования, распаковывает образ целиком в верхнюю память и монтирует RAM-диск, если он предусмотрен.[5] После этого она выполняет запуск ядра посредством ./arch/x86/boot/head и процесса startup_32() (для процессоров семейства x86).
Этап запуска ядра- Источник: Описание процесса загрузки Linux фирмой «IBM» (англ.) + переведённая версия с того же сайта Подробности процесса загрузки Linux (рус.)
Функция запуска ядра (также называемая своппер или процесс 0) организует управление памятью (таблицы страниц и страничную организацию памяти), определяет тип процессора и дополнительные возможности (например, наличие математического сопроцессора), а затем переключается к архитектурно-независимому функционалу ядра Linux путём вызова start_kernel() .
start_kernel() выполняет множество задач инициализации. Она настраивает обработчики прерываний (IRQ), затем настраивает память, запускает процесс init (первый процесс пользовательского режима), а затем запускает задачу бездействия вызовом cpu_idle() . Следует заметить, что процесс запуска ядра также монтирует инициирующий RAM-диск («initrd»), который ранее был загружен в роли временной корневой файловой системы в фазе загрузки. Это позволяет загружать модули драйверов, не опираясь на другие физические устройства и драйверы, и поддерживать небольшой размер ядра. Корневая файловая система впоследствии подменяется с помощью вызова pivot_root() , который размонтирует временную и заменяет её настоящей корневой ФС, как только последняя станет доступна. Использованная временной системой память затем освобождается.
Таким образом, ядро инициализирует устройства, монтирует указанную загрузчиком файловую систему в режиме «только чтение» и запускает процесс init (/sbin/init ), который обозначается как первый процесс, запущенный системой (с идентификатором процесса PID = 1).[1] Соответствующие сообщения выводит ядро (при монтировании файловой системы) и init (при запуске одноимённого процесса). Ядро также может выполнить initrd для обработки настроек и инициализации устройств до монтирования корневой файловой системы.[1]
По заявлению компании «Red Hat», детали процесса загрузки на этом этапе можно подытожить так:[2]
Когда загружается ядро, оно сразу же инициализирует и конфигурирует память компьютера и настраивает различное подключённое к системе оборудование, включая все процессоры, подсистемы ввода-вывода и устройства хранения данных. Затем оно ищет сжатый образ initrd в заранее определённом участке памяти, распаковывает его, монтирует и загружает все необходимые драйверы. Затем оно инициализирует виртуальные устройства, связанные с файловой системой, например LVM или программные RAID-массивы, прежде чем демонтировать образ диска initrd и освободить всю память, ранее занимаемую образом. Потом ядро создает корневое устройство, монтирует корневой раздел только для чтения и освобождает всю неиспользованную память. К этому времени ядро загружено в память и работоспособно. Тем не менее, поскольку нет пользовательских программ для осуществления осмысленного ввода данных в систему, с ней мало что можно делать.
Теперь, когда включены прерывания, диспетчер может принять общее управление системой, чтобы обеспечить вытесняющую многозадачность, а процесс init остается продолжать загрузку пользовательского окружения в пространстве пользователя.
Процесс init (только типа UNIX System V)
|
|