Глава 5. initramfs
Содержание
В этой главе мы рассмотрим зачем нам в действительности требуется initramfs и почему она важна в общем процессе запуска. Иы знаем, что initramfs загружается в память самим начальным загрузчиком, но мы пока не обсуждали как выделяется initramfs. Данная глава адресована этому. Мы также рассмотрим все этапы выделения, повторной сборки и персонализации initramfs. Затем мы рассмотрим собственно структуру initramfs, а также соответствующую последовательность запуска внутри initramfs.
основная цель процедуры запуска состоит в представлении своему пользователю его собственных файлов, которые
размещены в общей корневой файловой системе. Иными словами, именно для имеющегося ядра в обязанности входят поиск,
монтирование и представление такой корневой файловой системы своему пользователю. Для достижения этой цели наше ядро
обязано запустить соответствующий исполняемый файл systemd, который, опять же, располагается в корневой файловой
системе своего пользователя. Теперь это становится задачей курицы и яйца. Для запуска процесса systemd прежде всего
нам требуется смонтировать необходимую корневую файловую систему, а для монтирования такой корневой файловой системы
нам придётся запустить systemd из его корневой файловой системы. К тому же, помимо этой реальной корневой файловой
системы пользователи могут обладать файлами в некоторых прочих файловых системах, таких как NFS, CIFS и т.п., а этот
перечень прочих файловых систем также внутри устанавливаемой корневой файловой системы
(/etc/fstab
).
Итак, для решения нашей задачи курицы и яйца, разработчики пришли к решению с названием initramfs (что означает
"initial RAM filesystem", изначальная файловая система в оперативной памяти). initramfs является некой временной
корневой файловой системой (внутри своей оперативной памяти), которая будет применяться для монтирования своей реальной
корневой файловой системы (со своего жёсткого диска или из сетевой среды). Итак, вся цель initramfs заключается
в монтировании корневой файловой системы пользователя с его HDD/ из сети. В идеале наше ядро обладает достаточной
способностью для монтирования своей корневой файловой системы с диска в нём без initramfs, но в наши дни корневая файловая
система пользователя может быть где угодно. Она может располагаться в RAID, в неком LVM или в каком- то устройстве со
множеством путей. Может иметься некое число n
файловых систем, таких как
XFS, ext4, ext3, NFS и т.п.. Это может быть даже зашифрованная файловая система, например, LUKS. Итак, ядру практически
невозможно встроить все эти ситуации в своём собственном исполняемом файле vmlinux
.
Позвольте мне представить в этом разделе некие ситуации из реальной жизни.
Допустим, наша корневая файловая система расположена в NFS и нет никакого понятия об initramfs. Это означает, что наше ядро обязано смонтировать необходимую корневую файловую систему пользователя в самом себе из NFS. В таком случае, наше ядро должно осуществить следующие задачи:
-
поднять собственный первичный сетевой интерфейс.
-
Вызвать некого клиента DHCP и получить со своего сервера DHCP некий IP адрес.
-
Отыскать необходимый совместный ресурс NFS и связанный с ним сервер NFS.
-
Смонтировать этот совместный ресурс NFS (свою корневую файловую систему).
Для осуществления этих этапов нашему ядру потребуется обладать такими исполняемыми файлами:
NetworkManager
, dhclient
,
mount
и так далее.
Теперь, предположим, наша корневая файловая система находится на устройстве программного RAID. Тогда наше ядро обязано выполнить такие задачи:
-
Изначально отыскать необходимые диски RAID при помощи
mdadm --examine --scan
. -
После определения тех базовых диском, на которые распространяется этот программный RAID, ему требуется собрать этот RAID при помощи
mdadm --assemble --scan
-
Для достижения этого нашему ядру требуется обладать исполняемыми файлами
mount
иmdadm
, а также некоторыми файлами настройки своих устройств соответствующего программного RAID.
Теперь, допустим, наша корневая файловая система расположена в неком логическом томе. Тогда для нашего ядра требуется покончить со следующими задачами для самого себя:
-
Отыскать необходимые физические тома при помощи
pvs
. -
Найти необходимую группу томов посредством
vgscan
, а затем активировать её черезvgchange
. -
Просканировать полученный LVS воспользовавшись
lvscan
. -
наконец, после того как необходимый
root lv
заполнен, смонтировать его в качестве корневой файловой системы. -
Для достижения всего этого нашему ядру потребуется иметь исполняемый файлы, подобные
pvscan
,pvs
,lvscan
,vgscan
,lvs
иvgchange
.
Давайте предположим, что наша корневая файловая система находится на зашифрованном блочном устройстве. В этом случае нашему ядру придётся завершить следующие задачи:
-
Получить некий пароль от самого пользователя и/ или со вставленного аппаратного маркера (такого как смарт- карта или некий ключ безопасности USB).
-
Создать некую расшифрованную цель при помощи надлежащего устройства соответствия.
для получения всего этого нашему ядру необходимы исполняемые файлы, относящиеся к LUKS.
Для ядра не представляется возможным включать в себе возможности всех таких корневых файловых систем; следовательно, разработчики пришли к понятию initramfs, чья единственная цель состоит в монтировании необходимой корневой файловой системы.
Само ядро всё ещё способно выполнять все только что обсуждённые нами этапы. Например, если вы соберёте простую систему Linux командной строки из LFS, вам не понадобится монтировать некую корневую файловую систему, поскольку ядро само по себе достаточно в состоянии смонтировать необходимую файловую систему. Однако в тот момент, как вы попробуете добавить в неё GUI через BLFS, вам потребуется initramfs.
Итак, наше заключение состоит в том, что наше ядро способно смонтировать в самом себе необходимую корневую файловую
систему, однако для этого подобному ядру придётся удерживать все обсуждавшиеся исполняемые файлы, библиотеки
поддержки, файлы настройки и т.п. в своём файле vmlinuz
. Это создаст большое
число проблем.
-
Это испортит основной повод исполняемого самого файла ядра.
-
Исполняемый файл такого ядра будет гигантским в размере. Чем большим размером будет обладать исполняемый файл, тем сложнее его сопровождение.
-
Такой громадный исполняемый файл сложный в поддержке, обновлении, совместном использовании и обработке в серверах (с точки зрения пакетов RPM).
-
Этот подход не будет следовать правилу KISS (keep it simple, stupid - делай проще, тупица).
Чтобы разобраться со структурой initramfs, нам внечале нужно освоить три различные файловые системы.
Для более простого понимания, мы будем сравнивать ramfs с соответствующим механизмом кэширования ядра. Linux обладает некой уникальной функциональной возможностью, носящей название страничного кэша (page cache). Всякий раз, когда вы выполняете любую транзакцию ввода/ вывода, он кэширует эти транзакции страницами. Кэширование страницами в памяти это всегда хорошо. Это будет экономить наши последующие транзакции ввода/ вывода. И всякий раз, когда наша система сталкивается с ситуацией недостаточности памяти, наше ядро просто избавляется в памяти от таких кэшированны страниц. ramfs в точности как наше кэширование памяти. Однако основная проблема с ramfs состоит в том, что она не обладает стоящим за нею хранилищем; следовательно, она не способна выгружать свои страницы (устройство подкачки - swap, это опять- таки устройтво храенния). Итак, очевидно, что наше ядро не будет способно освобождать эту память, ибо не существует места для сохранения этих страниц. Следовательно, ramfs будет продолжать расти и не способна на практике ограничивать свой размер. Что мы можем сделать для упрощения данного положения вещей, так это допускать запись в ramfs лишь пользователю root.
tmpfs в точности как ramfs, но с некоторыми дополнениями. Мы способны накладывать некий предел на размер tmpfs, чего мы не способны делать в ramfs. Кроме того, страницы tmpfs могут использовать пространство подкачки.
rootfs это некая tmpfs которая выступает экземпляром ramfs. Основное преимущество rootfs заключается в том, что у вас
нет возможности отмены её монтирования. Это происходит по той же самой причине, по которой вы не способны уничтожить
свой процесс systemd
.
initramfs использует ramfs в качестве файловой системы и то пространство, которое занимается в памяти со стороны initramfs будет высвобождено после монтирования необходимой корневой файловой системы пользователя.
# dmesg | grep Free
[ 0.813330] Freeing SMP alternatives memory: 36K
[ 3.675187] Freeing initrd memory: 32548K <<<=======<<<<<<===== NOTE
[ 5.762702] Freeing unused decrypted memory: 2040K
[ 5.767001] Freeing unused kernel image memory: 2272K
[ 5.776841] Freeing unused kernel image memory: 2016K
[ 5.783116] Freeing unused kernel image memory: 1580K
Раньше, вместо initramfs Linux применял initrd
(initial RAM disk), однако
initrd
теперь признан устаревшим, а следовательно мы лишь перечислим несколько
важных моментов для его сопоставления с initramfs.
- initrd
Будучи отформатированным/ рассматриваемым в качестве некого блочного устройства, это подразумевает что
initrd
не обладает возможностью масштабирования. Что означает, что псле того как вы привнеси в памятьinitrd
и рассматриваете его в качестве некого блочного устройства, вы не способны увеличивать или уменьшать его размер.Мы впустую тратим некую оперативную память в кэше, поскольку
initrd
рассматривается в качестве блочного устройства, ибо само ядро Linux спроектировано для удержания содержимого своего блочного устройства в кэше для снижения транзакций ввода/ вывода. Короче говоря, нет необходимости в кэшировании содержимогоinitrd
самим ядром, так ак оно уже в памяти.
- initramfs
В
initrd
всегда будут иметься накладные расходы на драйверы его файловой системы и исполняемых файлов, таких какmke2fs
. Подобная командаmke2fs
применяется для создания файловых систем ext2/3/4. Это означает, что часть области оперативной памяти будет вначале форматироваться при помощи такой файловой системы ext2/3/4 при помощиmke2fs
, а затем из неё будет извлекатьсяinitrd
, тогда какinitramfs
, так же как и tmpfs, которую вы способны наращивать или усекать на лету.Не существует дублирования данных между блочными устройствами и кэшем.
Для применения тогда как
initramfs
в качестве корневой файловой системы, нашему ядру не требуется никакой драйвер или исполняемый файл, подобныйmke2fs
, поскольку тогда как достижениеinitramfs
произойдёт выделением в основной памяти как таковой.
# ls -lh /boot/initramfs-5.3.7-301.fc31.x86_64.img
-rw-------. 1 root root 32M Dec 9 10:19 /boot/initramfs-5.3.7-301.fc31.x86_64.img
Для просмотра содержимого initramfs мы можем воспользоваться инструментом lsinitrd
,
или же мы можем распаковать initramfs с помощью соответствующего инструментария
skipcpio
#lsinitrd
<snip>
Image: /boot/initramfs-5.3.7-301.fc31.x86_64.img: 32M
========================================================================
Early CPIO image
========================================================================
drwxr-xr-x 3 root root 0 Jul 25 2019 .
-rw-r--r-- 1 root root 2 Jul 25 2019 early_cpio
drwxr-xr-x 3 root root 0 Jul 25 2019 kernel
drwxr-xr-x 3 root root 0 Jul 25 2019 kernel/x86
drwxr-xr-x 2 root root 0 Jul 25 2019 kernel/x86/microcode
-rw-r--r-- 1 root root 100352 Jul 25 2019 kernel/x86/microcode/GenuineIntel.bin
========================================================================
Version: dracut-049-27.git20181204.fc31.1
Arguments: -f
dracut modules:
bash
systemd
systemd-initrd
nss-softokn
i18n
network-manager
network
ifcfg
drm
plymouth
dm
kernel-modules
kernel-modules-extra
kernel-network-modules
lvm
qemu
qemu-net
resume
rootfs-block
terminfo
udev-rules
dracut-systemd
usrmount
base
fs-lib
shutdown
========================================================================
drwxr-xr-x 12 root root 0 Jul 25 2019 .
crw-r--r-- 1 root root 5, 1 Jul 25 2019 dev/console
crw-r--r-- 1 root root 1, 11 Jul 25 2019 dev/kmsg
crw-r--r-- 1 root root 1, 3 Jul 25 2019 dev/null
crw-r--r-- 1 root root 1, 8 Jul 25 2019 dev/random
crw-r--r-- 1 root root 1, 9 Jul 25 2019 dev/urandom
lrwxrwxrwx 1 root root 7 Jul 25 2019 bin -> usr/bin
drwxr-xr-x 2 root root 0 Jul 25 2019 dev
drwxr-xr-x 11 root root 0 Jul 25 2019 etc
drwxr-xr-x 2 root root 0 Jul 25 2019 etc/cmdline.d
drwxr-xr-x 2 root root 0 Jul 25 2019 etc/conf.d
-rw-r--r-- 1 root root 124 Jul 25 2019 etc/conf.d/systemd.conf
-rw-r--r-- 1 root root 0 Jul 25 2019 etc/fstab.empty
-rw-r--r-- 1 root root 240 Jul 25 2019 etc/group
-rw-r--r-- 1 root root 22 Jul 25 2019 etc/hostname
lrwxrwxrwx 1 root root 25 Jul 25 2019 etc/initrd-release -> ../usr/lib/initrd-release
-rw-r--r-- 1 root root 8581 Jul 25 2019 etc/ld.so.cache
-rw-r--r-- 1 root root 28 Jul 25 2019 etc/ld.so.conf
drwxr-xr-x 2 root root 0 Jul 25 2019 etc/ld.so.conf.d
-rw-r--r-- 1 root root 17 Jul 25 2019 etc/ld.so.conf.d/libiscsi-x86_64.conf
-rw-rw-r-- 1 root root 19 Jul 25 2019 etc/locale.conf
drwxr-xr-x 2 root root 0 Jul 25 2019 etc/lvm
-rw-r--r-- 1 root root 102256 Jul 25 2019 etc/lvm/lvm.conf
-rw-r--r-- 1 root root 2301 Jul 25 2019 etc/lvm/lvmlocal.conf
-r--r--r-- 1 root root 33 Jul 25 2019 etc/machine-id
drwxr-xr-x 2 root root 0 Jul 25 2019 etc/modprobe.d
</snip>
Для распаковки имеющегося содержимого initramfs воспользуйтесь исполняемым файлом skipcpio
из /usr/lib/dracut/skipcpio/
. Этот skipcpio
предоставляется инструментарием dracut. Мы обсудим dracut в Главе 6.
#/usr/lib/dracut/skipcpio initramfs-5.3.7-301.fc31.x86_64.img | gunzip -c | cpio -idv
Когда вы взглянете на распакованное содержимое initramfs, вы будете удивлены, узнав, что он выглядит в точности
как корневая файловая система пользователя. Обратите, пожалуйста, внимание не то, что мы распаковали initramfs в
своём каталоге /root/boot
.
# ls -lh /root/boot/
total 44K
lrwxrwxrwx. 1 root root 7 Mar 26 18:03 bin -> usr/bin
drwxr-xr-x. 2 root root 4.0K Mar 26 18:03 dev
drwxr-xr-x. 11 root root 4.0K Mar 26 18:03 etc
lrwxrwxrwx. 1 root root 23 Mar 26 18:03 init -> usr/lib/systemd/systemd
lrwxrwxrwx. 1 root root 7 Mar 26 18:03 lib -> usr/lib
lrwxrwxrwx. 1 root root 9 Mar 26 18:03 lib64 -> usr/lib64
drwxr-xr-x. 2 root root 4.0K Mar 26 18:03 proc
drwxr-xr-x. 2 root root 4.0K Mar 26 18:03 root
drwxr-xr-x. 2 root root 4.0K Mar 26 18:03 run
lrwxrwxrwx. 1 root root 8 Mar 26 18:03 sbin -> usr/sbin
-rwxr-xr-x. 1 root root 3.1K Mar 26 18:03 shutdown
drwxr-xr-x. 2 root root 4.0K Mar 26 18:03 sys
drwxr-xr-x. 2 root root 4.0K Mar 26 18:03 sysroot
drwxr-xr-x. 2 root root 4.0K Mar 26 18:03 tmp
drwxr-xr-x. 8 root root 4.0K Mar 26 18:03 usr
drwxr-xr-x. 3 root root 4.0K Mar 26 18:03 var
Вы обнаружите каталоги, подобные bin
, sbin
,
usr
, etc
, var
,
lib
и lib64
, которые мы применяем чтобы
наблюдать свою корневую файловую систему. Помимо этого вы отметите соответствующие виртуальные каталоги, такие как
dev
, run
, proc
,
sys
и т.п.. Итак, initramfs в очности подобна корневой файловой системе пользователя.
Давайте изучим каждый из каталогов для лучшего понимания своей реализации initramfs.
Теперь мы рассмотрим как само содержимое initrafs, так и то как именно организована initrafs. На протяжении данного раздела мы разберёмся с тем, что initramfs ни что иное как небольшая корневая файловая система.
Обычные исполняемые файлы
Мы можем использовать все приводимые ниже исполняемые файлы системы, которая закончила свою процедуру запуска. Поскольку все эти исполняемые файлы доступны внутри initramfs при продолжающемся запуске данной системы, мы будем иметь возможность применения этих команд в момент данного запуска.
cat, chown, cp, dmesg, echo, grep, gzip, less, ln, mkdir, mv, ps, rm, sed, sleep, umount, uname, vi, loadkeys, kbd_mode, flock, tr, true, stty, mount, sort и т.п.
[root@fedorab boot]# ls -la bin/
total 7208
drwxr-xr-x. 2 root root 4096 Jan 10 12:01 .
drwxr-xr-x. 8 root root 4096 Dec 19 14:30 ..
-rwxr-xr-x. 1 root root 1237376 Dec 19 14:30 bash
-rwxr-xr-x. 1 root root 50160 Dec 19 14:30 cat
-rwxr-xr-x. 1 root root 82688 Dec 19 14:30 chown
-rwxr-xr-x. 1 root root 177144 Dec 19 14:30 cp
-rwxr-xr-x. 1 root root 89344 Dec 19 14:30 dmesg
-rwxr-xr-x. 1 root root 2666 Dec 19 14:30 dracut-cmdline
-rwxr-xr-x. 1 root root 422 Dec 19 14:30 dracut-cmdline-ask
-rwxr-xr-x. 1 root root 1386 Dec 19 14:30 dracut-emergency
-rwxr-xr-x. 1 root root 2151 Dec 19 14:30 dracut-initqueue
-rwxr-xr-x. 1 root root 1056 Jan 10 12:01 dracut-mount
-rwxr-xr-x. 1 root root 517 Dec 19 14:30 dracut-pre-mount
-rwxr-xr-x. 1 root root 928 Dec 19 14:30 dracut-pre-pivot
-rwxr-xr-x. 1 root root 482 Dec 19 14:30 dracut-pre-trigger
-rwxr-xr-x. 1 root root 1417 Dec 19 14:30 dracut-pre-udev
-rwxr-xr-x. 1 root root 45112 Dec 19 14:30 echo
-rwxr-xr-x. 1 root root 76768 Dec 19 14:30 findmnt
-rwxr-xr-x. 1 root root 38472 Dec 19 14:30 flock
-rwxr-xr-x. 1 root root 173656 Dec 19 14:30 grep
-rwxr-xr-x. 1 root root 107768 Dec 19 14:30 gzip
-rwxr-xr-x. 1 root root 78112 Dec 19 14:30 journalctl
-rwxr-xr-x. 1 root root 17248 Dec 19 14:30 kbd_mode
-rwxr-xr-x. 1 root root 387504 Dec 19 14:30 kmod
-rwxr-xr-x. 1 root root 192512 Dec 19 14:30 less
-rwxr-xr-x. 1 root root 85992 Dec 19 14:30 ln
-rwxr-xr-x. 1 root root 222616 Dec 19 14:30 loadkeys
lrwxrwxrwx. 1 root root 4 Dec 19 14:30 loginctl -> true
-rwxr-xr-x. 1 root root 158056 Dec 19 14:30 ls
-rwxr-xr-x. 1 root root 99080 Dec 19 14:30 mkdir
-rwxr-xr-x. 1 root root 80264 Dec 19 14:30 mkfifo
-rwxr-xr-x. 1 root root 84560 Dec 19 14:30 mknod
-rwsr-xr-x. 1 root root 58984 Dec 19 14:30 mount
-rwxr-xr-x. 1 root root 169400 Dec 19 14:30 mv
-rwxr-xr-x. 1 root root 50416 Dec 19 14:30 plymouth
-rwxr-xr-x. 1 root root 143408 Dec 19 14:30 ps
-rwxr-xr-x. 1 root root 60376 Dec 19 14:30 readlink
-rwxr-xr-x. 1 root root 83856 Dec 19 14:30 rm
-rwxr-xr-x. 1 root root 127192 Dec 19 14:30 sed
-rwxr-xr-x. 1 root root 52272 Dec 19 14:30 setfont
-rwxr-xr-x. 1 root root 16568 Dec 19 14:30 setsid
lrwxrwxrwx. 1 root root 4 Dec 19 14:30 sh -> bash
-rwxr-xr-x. 1 root root 46608 Dec 19 14:30 sleep
-rwxr-xr-x. 1 root root 140672 Dec 19 14:30 sort
-rwxr-xr-x. 1 root root 96312 Dec 19 14:30 stat
-rwxr-xr-x. 1 root root 92576 Dec 19 14:30 stty
-rwxr-xr-x. 1 root root 240384 Dec 19 14:30 systemctl
-rwxr-xr-x. 1 root root 20792 Dec 19 14:30 systemd-cgls
-rwxr-xr-x. 1 root root 19704 Dec 19 14:30 systemd-escape
-rwxr-xr-x. 1 root root 62008 Dec 19 14:30 systemd-run
-rwxr-xr-x. 1 root root 95168 Dec 19 14:30 systemd-tmpfiles
-rwxr-xr-x. 1 root root 173752 Dec 19 14:30 teamd
-rwxr-xr-x. 1 root root 58400 Dec 19 14:30 tr
-rwxr-xr-x. 1 root root 45112 Dec 19 14:30 true
-rwxr-xr-x. 1 root root 442552 Dec 19 14:30 udevadm
-rwsr-xr-x. 1 root root 41912 Dec 19 14:30 umount
-rwxr-xr-x. 1 root root 45120 Dec 19 14:30 uname
-rwxr-xr-x. 1 root root 1353704 Dec 19 14:30 vi
Особые исполняемые файлы
Специальный исполняемый файл | Назначение |
---|---|
|
initramfs снабжает нас некой оболочкой на момент запуска. |
|
Мы будем обладать способностью создания устройств. dracut применяет
|
|
Некий инструментарий управления имеющимися модулями ядра. |
Сетевые исполняемые файлы
Существует доступным в bin
лишь единственный исполняемый файл, относящийся к
сетевым ресурсам и им выступает teamd
(initramfs способен обрабатывать собранные
в группу сетевые устройства).
Особые точки входа
В Главе 7 и в Главе 9 мы обсудим особые точки входа.
dracut-cmdline dracut-cmdline-ask
dracut-emergency dracut -initqueue
dracut-mount dracut -pre-pivot
dracut - pre-trigger dracut -pre-udev
Исполняемые файлы Systemd
Исполняемый файл | Назначение |
---|---|
|
Это прародитель всех процессов, который заменил собой
|
|
Диспетчер службы systemd. |
|
Будет перечислять существующие группы управления (cgroups, control groups). |
|
Преобразует получаемую строку в формат элемента systemd, также носящего название экранированного (escaped). |
|
Способен запускать полученные программы в виде некой службы, но в переходном режиме. |
|
Создаёт, удаляет и вычищает не постоянные и временные файлы и катоалоги. |
|
Некий инструмент, который имеет дело с журналом systemd. |
Исполняемые файлы файловой системы и относящиеся к хранению программы.
Исполняемый файл | Назначение |
---|---|
|
Считать атрибуты устройства. |
|
Изменить устройство корневой текущей файловой системы. |
|
Проверить файловые системы ext2/3/4. |
|
Проверить и восстановить соответствующую файловую систему. |
|
Когда вы желаете остановить имеющееся устройство подкачки. |
|
Инструмент установки соответствия для упраовления LVM. |
|
Демеон событий соответствия устройств. |
|
Инструмент управления LVM, который предоставляет команды
|
|
Сценарий поиска устройств LVM. |
Сетевые исполняемые файлы
Исполняемый файл | Назначение |
---|---|
|
Для полусения IP от имеющегося сервера DHCP. |
|
Для настройки устройства |
|
Для поддержки |
|
Некий инструментарий управления имеющимися сетевыми устройствами. |
Особые исполняемые файлы
Исполняемый файл | Назначение |
---|---|
|
Для генерации |
|
Для просмотра загруженных модулей (символической ссылки - symlink
|
|
Для выдачи на печать сведений о модуле (символической ссылки - symlink
|
|
Для загрузки или вставки модулей (символической ссылки - symlink
|
|
Для удаления загруженного модуля (символической ссылки - symlink
|
|
Первый процесс. |
|
kexec ядра, используемый Kdump. |
|
Диспетчер Udev. |
Базовые исполняемые файлы
Наконец, вот имеющиеся базовые исполняемые файлы:
Halt, poweroff, reboot
[root@fedorab boot]# ls -lah sbin/
total 13M
drwxr-xr-x. 2 root root 4.0K Dec 19 14:30 .
drwxr-xr-x. 8 root root 4.0K Dec 19 14:30 ..
-rwxr-xr-x. 1 root root 126K Dec 19 14:30 blkid
-rwxr-xr-x. 1 root root 50K Dec 19 14:30 chroot
lrwxrwxrwx. 1 root root 11 Dec 19 14:30 depmod -> ../bin/kmod
-rwxr-xr-x. 1 root root 2.9M Dec 19 14:30 dhclient
-r-xr-xr-x. 1 root root 45K Dec 19 14:30 dmeventd
-r-xr-xr-x. 1 root root 159K Dec 19 14:30 dmsetup
-rwxr-xr-x. 2 root root 340K Dec 19 14:30 e2fsck
-rwxr-xr-x. 1 root root 58K Dec 19 14:30 fsck
-rwxr-xr-x. 2 root root 340K Dec 19 14:30 fsck.ext4
lrwxrwxrwx. 1 root root 16 Dec 19 14:30 halt -> ../bin/systemctl
lrwxrwxrwx. 1 root root 22 Dec 19 14:30 init -> ../lib/systemd/systemd
-rwxr-xr-x. 1 root root 1.2K Dec 19 14:30 initqueue
lrwxrwxrwx. 1 root root 11 Dec 19 14:30 insmod -> ../bin/kmod
-rwxr-xr-x. 1 root root 197 Dec 19 14:30 insmodpost.sh
-rwxr-xr-x. 1 root root 203K Dec 19 14:30 kexec
-rwxr-xr-x. 1 root root 496 Dec 19 14:30 loginit
-rwxr-xr-x. 1 root root 117K Dec 19 14:30 losetup
lrwxrwxrwx. 1 root root 11 Dec 19 14:30 lsmod -> ../bin/kmod
-r-xr-xr-x. 1 root root 2.4M Dec 19 14:30 lvm
-rwxr-xr-x. 1 root root 3.5K Dec 19 14:30 lvm_scan
lrwxrwxrwx. 1 root root 11 Dec 19 14:30 modinfo -> ../bin/kmod
lrwxrwxrwx. 1 root root 11 Dec 19 14:30 modprobe -> ../bin/kmod
-rwxr-xr-x. 1 root root 2.7K Dec 19 14:30 netroot
-rwxr-xr-x. 1 root root 5.3M Dec 19 14:30 NetworkManager
-rwxr-xr-x. 1 root root 16K Dec 19 14:30 nologin
-rwxr-xr-x. 1 root root 150K Dec 19 14:30 plymouthd
lrwxrwxrwx. 1 root root 16 Dec 19 14:30 poweroff -> ../bin/systemctl
-rwxr-xr-x. 1 root root 1.4K Dec 19 14:30 rdsosreport
lrwxrwxrwx. 1 root root 16 Dec 19 14:30 reboot -> ../bin/systemctl
lrwxrwxrwx. 1 root root 11 Dec 19 14:30 rmmod -> ../bin/kmod
-rwxr-xr-x. 1 root root 25K Dec 19 14:30 swapoff
-rwxr-xr-x. 1 root root 6.0K Dec 19 14:30 tracekomem
lrwxrwxrwx. 1 root root 14 Dec 19 14:30 udevadm -> ../bin/udevadm
Разве не удивительно, что не обладая реальной корневой файловой системой пользователя мы имеем возможность применять оболочку, сетевую среду, модули, устройства и т.п., а также управлять ими? Иными словами, вам и в самом деле не требуется корневая файловая система пользователя пока пользователь не пожелает получить досткп к своим частным файлам, но это просто шутка.
Теперь возникает вопрос: где и как мы можем применять эти команды? Эти исполняемые файлы и команды будут автоматически применяться initramfs. Или, говоря правильно, эти исполняемые файлы и команды мы будем применять systemd initramfs для монтирования реальной корневой файловой системы пользователя, но, если systemd завершит это отказом, он предоставит нам некую оболочку и мы будем иметь возможность применять эти команды и устранять впоследствии неисправности. Мы обсудим это в Главе 7, Главе 8 и Главе 9.
Имеющиеся в каталогах bin
и sbin
исполняемые
файлы будут иметь собственные файлы настроек и они будут храниться в соответствующем каталоге
etc
initramfs.
[root@fedorab boot]# tree etc/
etc/
├── cmdline.d
├── conf.d
│ └── systemd.conf
├── fstab.empty
├── group
├── hostname
├── initrd-release -> ../usr/lib/initrd-release
├── ld.so.cache
├── ld.so.conf
├── ld.so.conf.d
│ └── libiscsi-x86_64.conf
├── locale.conf
├── lvm
│ ├── lvm.conf
│ └── lvmlocal.conf
├── machine-id
├── modprobe.d
│ ├── firewalld-sysctls.conf
│ ├── kvm.conf
│ ├── lockd.conf
│ ├── mlx4.conf
│ ├── nvdimm-security.conf
│ └── truescale.conf
├── mtab -> /proc/self/mounts
├── os-release -> initrd-release
├── passwd
├── plymouth
│ └── plymouthd.conf
├── sysctl.conf
├── sysctl.d
│ └── 99-sysctl.conf -> ../sysctl.conf
├── systemd
│ ├── journald.conf
│ └── system.conf
├── system-release -> ../usr/lib/fedora-release
├── udev
│ ├── rules.d
│ │ ├── 11-dm.rules
│ │ ├── 59-persistent-storage-dm.rules
│ │ ├── 59-persistent-storage.rules
│ │ ├── 61-persistent-storage.rules
│ │ └── 64-lvm.rules
│ └── udev.conf
├── vconsole.conf
└── virc
10 directories, 35 files
Виртуальные файловые системы являются определённым видом файловых систем, чьи файлы в реальности не присутствуют на
диске; вместо этого данная файловая система целиком доступна в памяти. Это имеет свои собственные преимущества и недостатки;
например, вы получаете очень высокую пропускную способность , однако эта файловая система не способна хранить свои
данные на постоянной основе. Внутри initramfs существует три виртуальные файловые системы, которыми выступают
dev
, proc
и
sys
. Здесь я дал некое краткое введение в эти файловые системы, но мы обсудим
их подробнее своих последующих главах:
[root@fedorab boot]# ls -lah dev
total 8.0K
drwxr-xr-x. 2 root root 4.0K Dec 19 14:30 .
drwxr-xr-x. 12 root root 4.0K Dec 19 14:33 ..
crw-r--r--. 1 root root 5, 1 Dec 19 14:30 console
crw-r--r--. 1 root root 1, 11 Dec 19 14:30 kmsg
crw-r--r--. 1 root root 1, 3 Dec 19 14:30 null
crw-r--r--. 1 root root 1, 8 Dec 19 14:30 random
crw-r--r--. 1 root root 1, 9 Dec 19 14:30 urandom
[root@fedorab boot]# ls -lah proc/
total 8.0K
drwxr-xr-x. 2 root root 4.0K Dec 19 14:30 .
drwxr-xr-x. 12 root root 4.0K Dec 19 14:33 ..
[root@fedorab boot]# ls -lah sys/
total 8.0K
drwxr-xr-x. 2 root root 4.0K Dec 19 14:30 .
drwxr-xr-x. 12 root root 4.0K Dec 19 14:33 ..
dev
На данный момент существует лишь пять файлов устройств по умолчанию, но при запуске данной системы
udev
полностью запонит данный каталог. Файлы устройств
console
, kmsg
,
null
, random
и
urandom
будут создаваться самим ядром, или, иначе говоря, эти устройства
создаются вручную при помощи команды mknod
, однако все остальные файлы
создаются udev
.
proc и sys
Как только наше ядро получает контроль над выполняемой процедурой запуска, это ядро создаст и заполнит эти каталоги.
Файловая система proc
будет хранить все связанные с процессами сведения, например,
/proc/1/status
, в то время как sys
будет хранить сведения об имеющихся устройствах и связанную с их драйверами, например,
/sys/fs/ext4/sda5/errors_count
.
Как мы знаем, в эти дни usr
это отдельная иерархия в общей корневой
файловой системой. Наши /bin
, /sbin
,
/lib
и /lib64
являются ничем иным как
всего лишь символическими ссылками на usr/bin
,
usr/sbin
, usr/lib
и
usr/lib64
.
# ls -l bin
lrwxrwxrwx. 1 root root 7 Dec 21 12:19 bin -> usr/bin
# ls -l sbin
lrwxrwxrwx. 1 root root 8 Dec 21 12:19 sbin -> usr/sbin
# ls -la usr
total 40
drwxr-xr-x. 8 root root 4096 Dec 21 12:19 .
drwxr-xr-x. 12 root root 4096 Dec 21 12:19 ..
drwxr-xr-x. 2 root root 4096 Dec 21 12:19 bin
drwxr-xr-x. 12 root root 4096 Dec 21 12:19 lib
drwxr-xr-x. 4 root root 12288 Dec 21 12:19 lib64
drwxr-xr-x. 2 root root 4096 Dec 21 12:19 libexec
drwxr-xr-x. 2 root root 4096 Dec 21 12:19 sbin
drwxr-xr-x. 5 root root 4096 Dec 21 12:19 share
# ls -la var
total 12
drwxr-xr-x. 3 root root 4096 Dec 21 12:19 .
drwxr-xr-x. 12 root root 4096 Dec 21 12:19 ..
lrwxrwxrwx. 1 root root 11 Dec 21 12:19 lock -> ../run/lock
lrwxrwxrwx. 1 root root 6 Dec 21 12:19 run -> ../run
drwxr-xr-x. 2 root root 4096 Dec 21 12:19 tmp
Существует почти 200 библиотек и почти все они предоставляются glibc
,
например, libc.so.6
Каталоги lib
и lib64
это всего лишь
символические ссылки на usr/lib
и
usr/lib64
.
# ls -l lib
lrwxrwxrwx. 1 root root 7 Dec 21 12:19 lib -> usr/lib
# ls -l lib64
lrwxrwxrwx. 1 root root 9 Dec 21 12:19 lib64 -> usr/lib64
# ls -la lib/
total 128
drwxr-xr-x. 12 root root 4096 Dec 21 12:19 .
drwxr-xr-x. 8 root root 4096 Dec 21 12:19 ..
drwxr-xr-x. 3 root root 4096 Dec 21 12:19 dracut
-rwxr-xr-x. 1 root root 34169 Dec 21 12:19 dracut-lib.sh
-rw-r--r--. 1 root root 31 Dec 21 12:19 fedora-release
drwxr-xr-x. 6 root root 4096 Dec 21 12:19 firmware
-rwxr-xr-x. 1 root root 6400 Dec 21 12:19 fs-lib.sh
-rw-r--r--. 1 root root 238 Dec 21 12:19 initrd-release
drwxr-xr-x. 6 root root 4096 Dec 21 12:19 kbd
drwxr-xr-x. 2 root root 4096 Dec 21 12:19 modprobe.d
drwxr-xr-x. 3 root root 4096 Dec 21 12:19 modules
drwxr-xr-x. 2 root root 4096 Dec 21 12:19 modules-load.d
-rwxr-xr-x. 1 root root 25295 Dec 21 12:19 net-lib.sh
lrwxrwxrwx. 1 root root 14 Dec 21 12:19 os-release -> initrd-release
drwxr-xr-x. 2 root root 4096 Dec 21 12:19 sysctl.d
drwxr-xr-x. 5 root root 4096 Dec 21 12:19 systemd
drwxr-xr-x. 2 root root 4096 Dec 21 12:19 tmpfiles.d
drwxr-xr-x. 3 root root 4096 Dec 21 12:19 udev
# ls -la lib64/libc.so.6
lrwxrwxrwx. 1 root root 12 Dec 21 12:19 lib64/libc.so.6 -> libc-2.30.so
# dnf whatprovides lib64/libc.so.6
glibc-2.30-5.fc31.x86_64 : The GNU libc libraries
Repo : @System
Matched from:
Filename : /lib64/libc.so.6
Достаточно просто разобраться в самом основном потоке последовательности запуска initramfs:
-
Поскольку initramfs вступает некой корневой файловой системой (
temporary
), она создаст то окружение, которое требуется для запуска его процессов. initramfs будет смонтирована в качестве корневой файловой системы (временный/
) и из неё будут запущены такие программы как systemd. -
После этого внутри временного каталога initramfs монтируется корневая файловая система некого нового пользователя с вашего HDD, либо из сетевой среды.
-
После того как внутри initramfs смонтирована корневая файловая система этого пользователя, имеющееся ядро запустит установленный исполняемый файл
init
, который не что иное как символическая ссылка наsystemd
, самый первый процесс в нашей операционной системе.# ls init -l lrwxrwxrwx. 1 root root 23 Dec 21 12:19 init -> usr/lib/systemd/systemd
-
Если всё успешно, имеющаяся временная корневая файловая система (корневая файловая система initramfs) будет размонтирована и обо всей остающейся последовательности запуска позаботится systemd. Запуск systemd будет рассмотрен в Главе 7.
Мы можем перепроверить на самом ли деле наше ядро запускает соответствующий процесс
init/systemd
сразу после раскрытия initramfs. Для этого мы можем
видоизменить свой сценарий init
, однако основным препятствием в этом выступает
то, что systemd
является исполняемым файлом, в то время как
init
применяется как некий сценарий. Мы запросто можем отредактировать
init
, поскольку он является файлом сценария, однако мы не способны
видоизменять исполняемый файл systemd
. Тем не менее, для хорошего
понимания и проверки нашей последовательности запуска на предмет того, что systemd
вызывается сразу после того, как имеющееся ядро распаковывает initramfs, мы применим систему н основе
init
. Это был бы достойный пример, ибо
systemd
в данном месте служит в качестве замены системе
init
. Кроме того, init
всё ещё
выступает символической ссылкой на systemd
. Мы воспользуемся системой
Centos 6, которая является дистрибутивом Linux на основе init
.
Прежде всего выделяем initramfs.
# zcat initramfs-2.6.32-573.el6.x86_64.img | cpio –idv
[root@localhost initramfs]# ls -lah
total 120K
drwxr-xr-x. 26 root root 4.0K Mar 27 12:56 .
drwxr-xr-x. 3 root root 4.0K Mar 27 12:56 ..
drwxr-xr-x. 2 root root 4.0K Mar 27 12:56 bin
drwxr-xr-x. 2 root root 4.0K Mar 27 12:56 cmdline
drwxr-xr-x. 3 root root 4.0K Mar 27 12:56 dev
-rw-r--r--. 1 root root 19 Mar 27 12:56 dracut-004-388.el6
drwxr-xr-x. 2 root root 4.0K Mar 27 12:56 emergency
drwxr-xr-x. 8 root root 4.0K Mar 27 12:56 etc
-rwxr-xr-x. 1 root root 8.8K Mar 27 12:56 init
drwxr-xr-x. 2 root root 4.0K Mar 27 12:56 initqueue
drwxr-xr-x. 2 root root 4.0K Mar 27 12:56 initqueue-finished
drwxr-xr-x. 2 root root 4.0K Mar 27 12:56 initqueue-settled
drwxr-xr-x. 2 root root 4.0K Mar 27 12:56 initqueue-timeout
drwxr-xr-x. 7 root root 4.0K Mar 27 12:56 lib
drwxr-xr-x. 3 root root 4.0K Mar 27 12:56 lib64
drwxr-xr-x. 2 root root 4.0K Mar 27 12:56 mount
drwxr-xr-x. 2 root root 4.0K Mar 27 12:56 netroot
drwxr-xr-x. 2 root root 4.0K Mar 27 12:56 pre-mount
drwxr-xr-x. 2 root root 4.0K Mar 27 12:56 pre-pivot
drwxr-xr-x. 2 root root 4.0K Mar 27 12:56 pre-trigger
drwxr-xr-x. 2 root root 4.0K Mar 27 12:56 pre-udev
drwxr-xr-x. 2 root root 4.0K Mar 27 12:56 proc
drwxr-xr-x. 2 root root 4.0K Mar 27 12:56 sbin
drwxr-xr-x. 2 root root 4.0K Mar 27 12:56 sys
drwxr-xr-x. 2 root root 4.0K Mar 27 12:56 sysroot
drwxrwxrwt. 2 root root 4.0K Mar 27 12:56 tmp
drwxr-xr-x. 8 root root 4.0K Mar 27 12:56 usr
drwxr-xr-x. 4 root root 4.0K Mar 27 12:56 var
Открываем файл init
и добавляем в него следующий баннер:
#vim init
"We are inside the init process. Init is replaced by Systemd"
<snip>
#!/bin/sh
#
# Licensed under the GPLv2
#
# Copyright 2008-2009, Red Hat, Inc.
# Harald Hoyer <harald@redhat.com>
# Jeremy Katz <katzj@redhat.com>
echo "we are inside the init process. Init is replaced by Systemd"
wait_for_loginit()
{
if getarg rdinitdebug; then
set +x
exec 0<>/dev/console 1<>/dev/console 2<>/dev/console
# wait for loginit
i=0
while [ $i -lt 10 ]; do
.
.
.
</snip>
>
Повторно упакуем initramfs с названием test.img
.
[root@localhost initramfs]# find . | cpio -o -c | gzip -9 > /boot/test.img
163584 blocks
# ls -lh /boot/
total 66M
-rw-r--r--. 1 root root 105K Jul 23 2015 config-2.6.32-573.el6.x86_64
drwxr-xr-x. 3 root root 1.0K Aug 7 2015 efi
-rw-r--r--. 1 root root 163K Jul 20 2011 elf-memtest86+-4.10
drwxr-xr-x. 2 root root 1.0K Dec 21 16:12 grub
-rw-------. 1 root root 27M Dec 21 15:55 initramfs-2.6.32-573.el6.x86_64.img
-rw-------. 1 root root 5.3M Dec 21 16:03 initrd-2.6.32-573.el6.x86_64kdump.img
drwx------. 2 root root 12K Dec 21 15:54 lost+found
-rw-r--r--. 1 root root 162K Jul 20 2011 memtest86+-4.10
-rw-r--r--. 1 root root 202K Jul 23 2015 symvers-2.6.32-573.el6.x86_64.gz
-rw-r--r--. 1 root root 2.5M Jul 23 2015 System.map-2.6.32-573.el6.x86_64
-rw-r--r--. 1 root root 27M Mar 27 13:16 test.img
-rwxr-xr-x. 1 root root 4.1M Jul 23 2015 vmlinuz-2.6.32-573.el6.x86_64
Запустим новый initramfs test.img
и вы заметите что сразу после распаковки
initramfs был выведен на печать наш баннер.
<snip>
.
.
.
cpuidle: using governor ladder
cpuidle: using governor menu
EFI Variables Facility v0.08 2004-May-17
usbcore: registered new interface driver hiddev
usbcore: registered new interface driver usbhid
usbhid: v2.6:USB HID core driver
GRE over IPv4 demultiplexor driver
TCP cubic registered
Initializing XFRM netlink socket
NET: Registered protocol family 17
registered taskstats version 1
rtc_cmos 00:01: setting system clock to 2020-03-27 07:53:44 UTC (1585295624)
Initalizing network drop monitor service
Freeing unused kernel memory: 1296k freed
Write protecting the kernel read-only data: 10240k
Freeing unused kernel memory: 732k freed
Freeing unused kernel memory: 1576k freed
we are inside the init process. Init is replaced by Systemd
dracut: dracut-004-388.el6
dracut: rd_NO_LUKS: removing cryptoluks activation
device-mapper: uevent: version 1.0.3
device-mapper: ioctl: 4.29.0-ioctl (2014-10-28) initialised: dm-devel@redhat.com
udev: starting version 147
dracut: Starting plymouth daemon
.
.
</snip>
Задержимся на минутку чтобы попытаться восстановить всё что мы изучили на данный момент.
-
Самым первым запускается начальный загрузчик.
-
Этот начальный загрузчик копирует в память необходимые ядро и initramfs.
-
Ядро распаковывает себся самостоятельно.
-
Наш начальный загрузчик передал значение местоположения initramfs в устанавливаемое ядро.
-
Это ядро распаковывает в памяти initramfs.
-
Из распакованного initramfs наше ядро запускает systemd.
Собственно распаковка происходит в файле ядра init/initramfs.c
. За это
выделение ответственна функция populate_rootfs
.
populate_rootfs function:
<snip>
.
.
646 static int __init populate_rootfs(void)
647 {
648 /* Load the built in initramfs */
649 char *err = unpack_to_rootfs(__initramfs_start, __initramfs_size);
650 if (err)
651 panic("%s", err); /* Failed to decompress INTERNAL initramfs */
652
653 if (!initrd_start || IS_ENABLED(CONFIG_INITRAMFS_FORCE))
654 goto done;
655
656 if (IS_ENABLED(CONFIG_BLK_DEV_RAM))
657 printk(KERN_INFO "Trying to unpack rootfs image as initramfs...\n");
658 else
659 printk(KERN_INFO "Unpacking initramfs...\n");
660
661 err = unpack_to_rootfs((char *)initrd_start, initrd_end - initrd_start);
662 if (err) {
663 clean_rootfs();
664 populate_initrd_image(err);
665 }
666
667 done:
668 /*
669 * If the initrd region is overlapped with crashkernel reserved region,
670 * free only memory that is not part of crashkernel region.
671 */
672 if (!do_retain_initrd && initrd_start && !kexec_free_initrd())
673 free_initrd_mem(initrd_start, initrd_end);
674 initrd_start = 0;
675 initrd_end = 0;
676
677 flush_delayed_fput();
678 return 0;
679 }
.
.
</snip>
unpack_to_rootfs function:
<snip>
.
.
443 static char * __init unpack_to_rootfs(char *buf, unsigned long len)
444 {
445 long written;
446 decompress_fn decompress;
447 const char *compress_name;
448 static __initdata char msg_buf[64];
449
450 header_buf = kmalloc(110, GFP_KERNEL);
451 symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL);
452 name_buf = kmalloc(N_ALIGN(PATH_MAX), GFP_KERNEL);
453
454 if (!header_buf || !symlink_buf || !name_buf)
455 panic("can't allocate buffers");
456
457 state = Start;
458 this_header = 0;
459 message = NULL;
460 while (!message && len) {
461 loff_t saved_offset = this_header;
462 if (*buf == '0' && !(this_header & 3)) {
463 state = Start;
464 written = write_buffer(buf, len);
465 buf += written;
466 len -= written;
467 continue;
468 }
469 if (!*buf) {
470 buf++;
471 len--;
472 this_header++;
473 continue;
474 }
475 this_header = 0;
476 decompress = decompress_method(buf, len, &compress_name);
477 pr_debug("Detected %s compressed data\n", compress_name);
478 if (decompress) {
479 int res = decompress(buf, len, NULL, flush_buffer, NULL,
480 &my_inptr, error);
481 if (res)
482 error("decompressor failed");
483 } else if (compress_name) {
484 if (!message) {
485 snprintf(msg_buf, sizeof msg_buf,
486 "compression method %s not configured",
487 compress_name);
488 message = msg_buf;
489 }
490 } else
491 error("invalid magic at start of compressed archive");
492 if (state != Reset)
493 error("junk at the end of compressed archive");
494 this_header = saved_offset + my_inptr;
495 buf += my_inptr;
496 len -= my_inptr;
497 }
498 dir_utime();
499 kfree(name_buf);
500 kfree(symlink_buf);
501 kfree(header_buf);
502 return message;
503 }
.
.
</snip>
Внутри функции populate_rootfs
имеется функция
unpack_to_rootfs
. Именно эта функция выступает исполнителем распаковки
initramfs и она возвращает 0
в случае отказа и
1
в случае успеха. Кроме того обратите внимание на занимательные
параметры этой функции:
-
__initramfs_start
: Это значение точного местоположения/ адреса загруженной initramfs (initramfs будет загружаться соответствующим начальным загрузчиком, а потому очевидно, что значение адреса местоположения также предоставляется этим начальным загрузчиком черезboot_protocol
). -
__initramfs_size
: Это значение размера образа загруженного initramfs.
Большой двоичный объект (blob) initramfs это просто некий файл cpio
(возможно сжатый). Наше ядро распаковывает его создавая в памяти некую файловую систему tmpfs/ramfs.
Поэтому на практике не существует некого фиксированного местоположения; Выделение памяти по мере распаковки выполняет
само ядро. Мы уже отмечали, что наш начальный загрузчик GRUB 2 помещает загружаемое ядро в определённом
местоположении, которое будет зависеть от архитектуры, однако распаковка образа initramfs не производится в
каком- то определённом месте.
Теперь, прежде чем мы мы проследуем далее в своей последовательности запуска , нам требуется разобраться с имеющимся инструментарием dracut, который создаётся initramfs. Этот инструментарий снабдит нас лучшим пониманием initramfs и systemd.