Хабрахабр

[Перевод] Введение в процессы загрузки ядра и запуска системы Linux

Всем привет! Вот мы и открыли очередной, четвёртый по счёт уже, поток курса «Администратор Linux», который уверенно занимают свою нишу рядом с девопсерским курсом. Больше преподавателей, больше информации и стендов. Ну и как всегда больше интересной информации, которую подобрали преподаватели.

Поехали.

Задумывались ли вы когда-нибудь, что нужно для того, чтобы ваша система была готова к запуску приложений?

В этой статье представлен обзор процесса загрузки ядра с использованием GRUB2 загрузчика и запуска, выполняемого системой инициализации systemd. Понимать процессы загрузки ядра и запуска системы Linux, важно для настройки Linux и решения проблем запуска.

Процесс загрузки ядра начинается при включении компьютера и заканчивается с инициализацией ядра и запуском systemd. На самом деле, есть два ряда событий, необходимых для приведения компьютера с Linux в рабочее состояние: загрузка ядра (boot) и запуск системы (startup). После этого начинается процесс запуска системы, и именно он доводит компьютер Linux до рабочего состояния.

Он состоит из следующих шагов, которые будут описываться более детально в разделах ниже: В целом, процесс загрузка ядра и запуск системы Linux довольно прост.

  • BIOS POST;
  • Загрузка ядра (GRUB2);
  • Инициализация ядра;
  • Запуск systemd, родителя всех процессов.

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

Процесс загрузки ядра

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

Это аппаратная часть процесса, одинаковая для всех операционных систем. BIOS POST

Первый шаг процесса загрузки ядра Linux не имеет никакого отношения к Linux. Когда питание подается на компьютер, в первую очередь происходит запуск POST (Power On Self Test), являющегося частью BIOS (Basic I/O System, Базовая Система Ввода-Вывода).

POST — часть BIOS, задачей которого является обеспечение корректной работы компьютерного оборудования. Когда IBM выпустила первый персональный компьютер в 1981 году, BIOS был разработан для инициализации аппаратных компонентов. Если POST заканчивается неудачно, то возможно компьютер неисправен, и процесс загрузки не продолжается.

Первый найденный сектор, в котором содержится валидная загрузочная запись, загружается в RAM, после чего контроль передается коду из загрузочного сектора.
Загрузочный сектор — только первый этап. BIOS POST проверяет базовую работоспособность железа, а затем вызывает прерывание BIOS — INT 13H, которое находит секторы загрузки ядра на всех подключенных устройствах с возможностью загрузки. GRUB2 — самый новый и сейчас его используют гораздо чаще более старых вариантов. В большинстве дистрибутивов Linux используется один из трех вариантов загрузчика: GRUB, GRUB2 и LILO.

GRUB2

GRUB2 — программа, которая делает компьютер достаточно “умным”, чтобы тот смог найти ядро операционной системы и загрузить его в память. GRUB2 расшифровывается как “GRand Unified Bootloader, version 2”, и теперь он является основным загрузчиком для большинства современных дистрибутивов Linux. Поскольку говорить и писать просто GRUB легче, чем GRUB2, в этой статье я возможно буду использовать термин GRUB, но подразумевать GRUB2, если не будет иного уточнения.

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

Это дает возможность загрузить предыдущую версию ядра, если обновленная не сможет загрузиться корректно или окажется несовместима с какой-то важной частью ПО. GRUB также позволяет пользователю выбрать загрузку ядра из нескольких возможных для любого предоставленного дистрибутива Linux. GRUB можно настроить в файл /boot/grub/grub.conf.

Дистрибутивы на основе Red Hat обновились до GRUB2 около Fedora 15 и CentOS/RHEL 7. GRUB1 сейчас уже считается устаревшим и в большинстве современных дистрибутивов заменен на GRUB2, который является его переписанным вариантом. Настройка GRUB2 происходит в /boot/grub2/grub.cfg. GRUB2 имеет тот же загрузочный функционал, что и GRUB1, но в дополнении предоставляет mainframe-like, pre-OS окружение на базе команд и бОльшую гибкость на предзагрузочном этапе.

Обе версии GRUB работают схожим образом в три этапа, но в этой статье я буду использовать именно GRUB2 для описания работы GRUB. Основная задача любого из GRUB — загрузить ядро Linux в память и запустить его. Настройка GRUB и GRUB2 и использование команд GRUB2 выходит за рамки этой статьи.

Хоть официально GRUB2 не использует нумерацию этапов, ради удобства я воспользуюсь ей в этой статье.

Этап 1

Bootstrap-код, то есть 1-ый этап GRUB2, занимает очень мало места, потому что должен влезать в первый 512-байтовый сектор на жестком диске вместе с таблицей разделов. Как уже упоминалось в разделе BIOS POST, в конце POST BIOS ищет загрузочные записи на прикрепленных дисках, обычно расположенных в Главной Загрузочной Записи (Master Boot Record, MBR), после чего он загружает первую найденную запись в память и приступает к ее исполнению. 446-байтовый файл для этапа 1 называется boot-img и не содержит таблицу разделов — она добавляется в загрузочную запись отдельно. Общее количество места, выделенного для самого bootstrap-кода в стандартной MBR — 446 байт.

Поэтому единственной целью этапа 1 является обнаружение и загрузка этапа 1. Поскольку загрузочная запись должна быть настолько маленькой, она не очень “умная” и не понимает структуру файловой системы. Чтобы достичь этого, этап 1. 5. После загрузки этапа 1. 5 GRUB должен располагаться в пространстве между самой загрузочной записью и первым разделом на диске. 5. 5 GRUB в RAM, этап 1 передает контроль этапу 1.

5 Этап 1.

5 GRUB должен находиться между загрузочной записью и первый разделом на диске. Как было замечено выше, этап 1. Первый раздел на жестком диске начинается в 63 секторе, а с учетом MBR в секторе 0, остается 62 512-байтовых секторов — 31744 байта — в которых можно хранить файл core.img — 1. Исторически сложилось, что это пространство остается неиспользованным по техническим причинам. Файл core.img весит 25389 байт, что достаточно места для его хранения между MBR и первым разделом диска. 5 этап GRUB.

5 можно использовать больше кода, его может быть достаточно для содержания нескольких распространенных драйверов файловых систем, например, стандартной EXT и прочих Linux файловых систем, FAT и NTFS. Поскольку для этапа 1. 5 GRUB1. core.ing в GRUB2 более сложный и функциональный, чем в этапе 1. Поэтому стандартное местоположение для файлов этапа 2 — файловая система /boot, а точнее /boot/grub2. Это значит, что этап 2 GRUB2 может находиться в стандартной EXT файловой системе, но не в логическом томе.

Не все файловые системы имеют эту поддержку. Обратим внимание, что директория /boot должна располагаться в файловой системе, которая поддерживается GRUB. 5 — начать с необходимыми драйверами файловой системы поиск файлов этапа 2 в файловой системе /boot и загрузить нужные драйверы. Задача этапа 1.

Этап 2

В GRUB2 нет файла образа как в этапах 1 и 2. Все файлы этапа 2 GRUB находятся в директории /boot/grub2 и нескольких поддиректориях. Вместо этого он по большей части состоит из runtime модулей ядра, которые грузятся по необходимости из директории /boot/grub2/i386-pc.

Ядро и связанные с ним файлы находятся в директории /boot. Задача этапа 2 GRUB2 — обнаружить и загрузить ядро Linux в RAM и передать контроль управления компьютером ядру. Вы можете составить список содержимого директории /boot, чтобы посмотреть текущие установленные ядра в вашей системе. Файлы ядра легко узнать, поскольку их названия начинаются с vmlinuz.

Система управления пакетами Red Hat поддерживает сохранение нескольких версий ядра, чтобы можно было загрузить старую версию ядра в случае возникновения проблем с самой новой. GRUB2, как и GRUB1, поддерживает загрузку одного из нескольких ядер Linux. По умолчанию, GRUB предоставляет предварительно загруженное меню установленные ядер, включая опцию rescue, а после настройки, и опцию recovery.

Этап 2 GRUB2 загружает выбранное ядро в память и передает контроль управления компьютером ядру.

Ядро

Ядра расположены в директории /boot, вместе с исходным образом диска RAM и списком разделов на жестких дисках. Все ядра находятся в самораспаковывающемся, сжатом формате для экономии места.

Как только извлечение произошло, оно загружает systemd, который является заменой старой программе SysV init, и передает ему контроль. После того, как выбранное ядро загружено в память и начинает исполняться, в первую очередь, оно должно извлечь самого себя из сжатой версии файла, перед тем как начать выполнять полезную работу.

К этому моменту, ядро Linux и systemd запущены, но не могут выполнять какие-либо полезные задачи для конечного пользователя, так как выполнять еще нечего. Это конец процесса загрузки ядра.

Процесс запуска системы

Процесс запуска системы следует за процессом загрузки ядра и приводит компьютер с Linux в рабочее состояние.

systemd

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

К этому моменту, он может получить доступ к файлам конфигурации, расположенным в /etc, включая его собственным. Сначала, systemd монтирует файловые системы, как определено в /etc/fstab, включая любые swap-файлы и разделы. Файл default.target — просто симлинк на настоящий target файл. Он использует собственный конфигурационный файл /etc/systemd/system/default.target, чтобы определить таргет (target), по которому нужно загрузить хост. Для сервера, по умолчанию скорее всего будет multi-user.target, аналогичный runlevel 3 в SystemV. Для настольной рабочей станции обычно это graphical.target, эквивалентный runlevel 5 в старом инициализаторе SystemV. emergency.target похож на однопользовательский режим.

Обратите внимание, что target’ы и сервисы являются юнитами systemd.

Псевдонимы таргета systemd предоставляются systemd для обратной совместимости. Ниже представлена Таблица 1, в которой идет сравнение всех таргетов systemd со старыми уровнями выполнения (runlevel) в SystemV. Конечно, команды SystemV направлены systemd для интерпретации и исполнения.
Псевдонимы таргета разрешают скриптам — и многим сисадминам, мне в том числе — использовать такие SystemV команды как init3 для изменения уровней выполнения.

SystemV Runlevel

systemd target

systemd target aliases

Description

halt.target

Приостанавливает систему без отключения питания

0

poweroff.target

runlevel0.target

Приостанавливает систему и отключает питание

S

emergency.target

Однопользовательский режим. Сервисы не запущены; файловые системы не смонтированы. Это самый базовый уровень оперирования. Для взаимодействия пользователя с системой в главной консоли запущена только аварийная оболочка.

1

rescue.target

runlevel1.target

Базовая система, включающая монтирование файловой системы с самым базовым набором сервисов и rescue оболочкой в главной консоли.

2

runlevel2.target

Многопользовательский режим, без NFS, но все сервисы, не относящиеся к GUI, запущены.

3

multi-user.target

runlevel3.target

Все сервисы запущены, но только через интерфейс командной строки (CLI).

4

runlevel4.target

Не используется.

5

graphical.target

runlevel5.target

Многопользовательский режим с GUI.

6

reboot.target

runlevel6.target

Перезагрузка.

default.target

Этот таргет всегда имеет симлинк с multi-user.target или graphical.target. systemd всегда использует default.target для запуска системы. default.target никогда не должен быть связан с halt.target, poweroff.target или reboot.target.

Таблица 1: Сравнение уровней управления SystemV с target’ами systemd и некоторые псевдонимы таргетов.

systemd запускает необходимые. У каждого таргета есть набор зависимостей, описанных в файле конфигурации. Когда все зависимости, перечисленные в конфигурационных файлах таргета, загружены и запущены, система работает на этом уровне таргета. Эти зависимости представляют собой сервисы, требуемые для запуска хоста Linux с определенным уровнем функционирования.

Если они есть, systemd использует их в качестве файлов конфигурации для запуска сервисов описанных в файлах. systemd также просматривает устаревшие директории инициализации SystemV на предмет наличия стартап файлов. Устаревший сетевой сервис — хороший пример одного из тех, что до сих пор используют стартап файлы SystemV в Fedora.

На нем показана общая последовательность событий во время запуска systemd и базовые требования для обеспечения его успешности. Рисунок 1, представленный ниже, напрямую скопирован с главной страницы bootup.

Хоть одна из целей systemd — параллельно запускать системная сервисы, есть некоторые сервисы и функциональные таргеты, которые должны быть запущены раньше других. Таргеты sysinit.target and basic.target можно считать чекпоинтами в процессе запуска системы. Эти контрольные точки не могут быть пройдены до тех пор, пока все сервисы и таргеты, необходимые для них, не будут выполнены.

Должны быть завершены все следующие юниты: монтирование файловых систем, настройка swap-файлов, запуск udev, настройка начального состояния генератора случайных чисел, инициализация низкоуровневых сервисов, настройка криптографических сервисов, если хотя бы одна файловая система зашифрована. Таким образом, sysinit.target достигается, когда завершены все юниты, от которых он зависит. В sysinit.target они могут выполняться параллельно.
sysinit.target запускает все низкоуровневые сервисы и юниты необходимые для минимальной функциональности системы, и те, что нужны для перехода к basic.target.

Карта запуска systemd
Рисунок 1.

Базовый таргет предоставляет дополнительный функционал, запуская юниты необходимые для следующего таргета, включая настройку путей до различных исполняемых директорий, коммуникационных сокетов и таймеров. После выполнения sysinit.target, systemd запускает basic.target, начиная со всех юнитов, необходимых для его выполнения.

Стоит отметить, что multi-user.target должен быть достигнут до того, как будут выполнены зависимости графического таргета. Наконец, можно начать инициализацию таргетов пользовательского уровня: multi-user.target или graphical.target.

Запуск системы завершается по достижении одного из них. Подчеркнутые таргеты в Рисунке 1 — обычные стартап таргеты. Если же по умолчанию задан graphical.target, то увидите графический логин; GUI экрана логина зависит от экранного менеджера, который вы используете. Если multi-user.target является таргетом по умолчанию, то в консоли вы увидите логин в текстовом режиме.

Проблемы

Я обнаружил, что некоторые команды перестали работать корректно, или же я пользовался ими как-то некорректно. Недавно мне пришлось поменять дефолтное загрузочное ядро на компьютере Linux, который использовал GRUB2. До сих пор не знаю, в чем была проблема, потребуется больше времени на ее исследование.

Я вручную поменял /etc/default/grub GRUB_DEFAULT=saved на GRUB_DEFAULT=2, где 2 — индекс установленного ядра, которое я хотел запустить. Команда grub2-set-default неправильно настроила дефолтный индекс ядра в файле /etc/default/grub, поэтому желаемое альтернативное ядро не загружалось. Эта уловка сработала, и альтернативное ядро было запущено. Затем, я запустил команду grub2-mkconfig > /boot/grub2/grub.cfg для создания нового конфигурационного файла grub.

Выводы

Несмотря на противоречия, особенно вокруг systemd, эти два компонента хорошо работаю вместе для загрузки ядра и запуска всех системных сервисов, необходимых для создания функциональной системы Linux.
Хоть я и считаю GRUB2 и systemd в целом более сложными, чем их предшественники, они ничуть не сложнее в освоении и управлении. GRUB2 и система инициализации systemd — ключевые компоненты для фаз загрузки ядра и запуска системы большинства современных дистрибутивов Linux. За большей информацией обратитесь к ссылкам ниже: В мануалах содержится большое количество информации о systemd, а на freedesktop.org список его страниц представлен полностью.

Ждём вопросы и комментарии тут или их можно задать напрямую на открытом уроке. Вот и всё.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть