Skip to content

presentation 2021 ru

Alexey Gladkov edited this page Sep 12, 2022 · 1 revision

make-initrd: генератор initramfs и не только

Alexey Gladkov, 2021

Abstract

Рассматривается задачи, архитектура проекта и существенные моменты его реализации.

Зачем ?

Технически, для загрузки системы на linux не требуется ничего кроме самого ядра linux. Для этого нужно вкомпилировать в него необходимые модули, firmware для них и поддержку файловой системы. Также можно указать по умолчанию устройство, которое нужно использовать в качестве корневого. Такое ядро загрузит систему на том железе, для которого оно было сконфигурировано.

Современные дистрибутивы поставляются под разные конфигурации систем и для разного железа. В этом случае конфигурация ядра "по месту" становится гораздо более сложной задачей.

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

Что же такое initramfs ?

Образ initramfs по сути является минимальным дистрибутивом, который не имеет возможности сохранить состояние. Этот дистрибутив работает считанные секунды, подготавливая окружение и передавая управление системному иниту.

В соверменных дистрибутивах значение этого микроинструмента настолько возросло, что большинство систем больше невозможно загрузить без него.

Как работает initramfs ?

Трюк состоит в том, что для ядра происходит "подмена понятий". Вместо сложной и непонятной ядру linux конфигурации мы "подсовываем" ему простую и понятную конфигурацию - ram-образ файловой системы. Запуская этот образ ядро linux понятия не имеет про остальную систему. После запуска init в initramfs ядро считает, что всё готово. Оно просто ждёт завершения процесса с pid=1.

Задача init из initramfs разобраться в конфигурации системы, загрузить необходимые для этой системы модули ядра, найти корневой раздел и передать управление init на этом резделе. Процесс init заменяет себя другим процессом, потому что ядро всё также следит только за pid=1.

Что такое make-initrd ?

В наши дни дистрибутивы создают великое множество разных вариантов разбивки диского пространства с использованием разных модулей ядра и системных утилит. Если поместить всё это в образ initramfs, то его размер будет со всю установленную систему (ну почти).

make-initrd - это генератор образов initramfs, содержащих необходимые компоненты для загрузки операционной системы с данным вариантом разбивки дисков.

Задача make-initrd - проанализировать текущее состояние системы и создать образ достаточный, чтобы повторить это состояние.

Проект разбит на три основные части:

  • Анализатор системы, который пытается угадать конфигурацию и фичи;
  • Генератор, создающий образ initramfs, на основе проанализированной конфигурации;
  • Код, который выполняется непосредственно в initramfs в момент загрузки системы.

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

Задача анализатора системы угадать, какие фичи нужно добавить в образ.

Код образа initramfs основывается на событиях, которые присылает ядро linux. Для обработки этих событий используется udev (userspace device management). При обработке событий порождаются новые события, на которые код initramfs снова реагирует. Процесс продолжается до тех пор, пока не будет найден корневой раздел системы с системным init.

Идея в том, чтобы инициализировать дисковую систему поэтапно, как матрёшку. Правда, в нашем случае для открытия каждой из матрёшек нужно иметь ключ. Если нет ключа, то продвинуться дальше не получится.

Какие "ключи" положить в образ решает анализатор. Генератор же положит как "ключи", так и дополнительную информацию необходимую для каждого "ключа".

Что make-initrd может ещё ?

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

Bootloader

Например, можно искать не коревой раздел с init, а раздел с каталогом /boot, содержащим другие версии ядра linux. После того, как раздел найден, то можно позволить пользователю выбрать нужную версию и загрузить её.

Netboot

Можно проинициализировать сетевую подсистему, загрузить с удалённого сервера образ системы и передать управление образу, не используя дискую подсистему вообще.

Installer

Можно проинициализовать cdrom, найти там сжатый образ установщика, распаковать и запустить его. Или же самостоятельно произвести разбиение дисков на разделы и распаковать образ на них.

Clone this wiki locally