Глава 5. initramfs

В этой главе мы рассмотрим зачем нам в действительности требуется 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. В таком случае, наше ядро должно осуществить следующие задачи:

  1. поднять собственный первичный сетевой интерфейс.

  2. Вызвать некого клиента DHCP и получить со своего сервера DHCP некий IP адрес.

  3. Отыскать необходимый совместный ресурс NFS и связанный с ним сервер NFS.

  4. Смонтировать этот совместный ресурс NFS (свою корневую файловую систему).

Для осуществления этих этапов нашему ядру потребуется обладать такими исполняемыми файлами: NetworkManager, dhclient, mount и так далее.

Теперь, предположим, наша корневая файловая система находится на устройстве программного RAID. Тогда наше ядро обязано выполнить такие задачи:

  1. Изначально отыскать необходимые диски RAID при помощи mdadm --examine --scan.

  2. После определения тех базовых диском, на которые распространяется этот программный RAID, ему требуется собрать этот RAID при помощи mdadm --assemble --scan

  3. Для достижения этого нашему ядру требуется обладать исполняемыми файлами mount и mdadm, а также некоторыми файлами настройки своих устройств соответствующего программного RAID.

Теперь, допустим, наша корневая файловая система расположена в неком логическом томе. Тогда для нашего ядра требуется покончить со следующими задачами для самого себя:

  1. Отыскать необходимые физические тома при помощи pvs.

  2. Найти необходимую группу томов посредством vgscan, а затем активировать её через vgchange.

  3. Просканировать полученный LVS воспользовавшись lvscan.

  4. наконец, после того как необходимый root lv заполнен, смонтировать его в качестве корневой файловой системы.

  5. Для достижения всего этого нашему ядру потребуется иметь исполняемый файлы, подобные pvscan, pvs, lvscan, vgscan, lvs и vgchange.

Давайте предположим, что наша корневая файловая система находится на зашифрованном блочном устройстве. В этом случае нашему ядру придётся завершить следующие задачи:

  1. Получить некий пароль от самого пользователя и/ или со вставленного аппаратного маркера (такого как смарт- карта или некий ключ безопасности USB).

  2. Создать некую расшифрованную цель при помощи надлежащего устройства соответствия.

для получения всего этого нашему ядру необходимы исполняемые файлы, относящиеся к LUKS.

Для ядра не представляется возможным включать в себе возможности всех таких корневых файловых систем; следовательно, разработчики пришли к понятию initramfs, чья единственная цель состоит в монтировании необходимой корневой файловой системы.

Само ядро всё ещё способно выполнять все только что обсуждённые нами этапы. Например, если вы соберёте простую систему Linux командной строки из LFS, вам не понадобится монтировать некую корневую файловую систему, поскольку ядро само по себе достаточно в состоянии смонтировать необходимую файловую систему. Однако в тот момент, как вы попробуете добавить в неё GUI через BLFS, вам потребуется initramfs.

Итак, наше заключение состоит в том, что наше ядро способно смонтировать в самом себе необходимую корневую файловую систему, однако для этого подобному ядру придётся удерживать все обсуждавшиеся исполняемые файлы, библиотеки поддержки, файлы настройки и т.п. в своём файле vmlinuz. Это создаст большое число проблем.

  • Это испортит основной повод исполняемого самого файла ядра.

  • Исполняемый файл такого ядра будет гигантским в размере. Чем большим размером будет обладать исполняемый файл, тем сложнее его сопровождение.

  • Такой громадный исполняемый файл сложный в поддержке, обновлении, совместном использовании и обработке в серверах (с точки зрения пакетов RPM).

  • Этот подход не будет следовать правилу KISS (keep it simple, stupid - делай проще, тупица).

Инфраструктура

Чтобы разобраться со структурой initramfs, нам внечале нужно освоить три различные файловые системы.

ramfs

Для более простого понимания, мы будем сравнивать ramfs с соответствующим механизмом кэширования ядра. Linux обладает некой уникальной функциональной возможностью, носящей название страничного кэша (page cache). Всякий раз, когда вы выполняете любую транзакцию ввода/ вывода, он кэширует эти транзакции страницами. Кэширование страницами в памяти это всегда хорошо. Это будет экономить наши последующие транзакции ввода/ вывода. И всякий раз, когда наша система сталкивается с ситуацией недостаточности памяти, наше ядро просто избавляется в памяти от таких кэшированны страниц. ramfs в точности как наше кэширование памяти. Однако основная проблема с ramfs состоит в том, что она не обладает стоящим за нею хранилищем; следовательно, она не способна выгружать свои страницы (устройство подкачки - swap, это опять- таки устройтво храенния). Итак, очевидно, что наше ядро не будет способно освобождать эту память, ибо не существует места для сохранения этих страниц. Следовательно, ramfs будет продолжать расти и не способна на практике ограничивать свой размер. Что мы можем сделать для упрощения данного положения вещей, так это допускать запись в ramfs лишь пользователю root.

tmpfs

tmpfs в точности как ramfs, но с некоторыми дополнениями. Мы способны накладывать некий предел на размер tmpfs, чего мы не способны делать в ramfs. Кроме того, страницы tmpfs могут использовать пространство подкачки.

rootfs

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.

Реализация initramfs

Теперь мы рассмотрим как само содержимое initrafs, так и то как именно организована initrafs. На протяжении данного раздела мы разберёмся с тем, что initramfs ни что иное как небольшая корневая файловая система.

bin

 

Обычные исполняемые файлы

Мы можем использовать все приводимые ниже исполняемые файлы системы, которая закончила свою процедуру запуска. Поскольку все эти исполняемые файлы доступны внутри 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
		
 

Особые исполняемые файлы

Таблица 5-1. Особые исполняемые файлы
Специальный исполняемый файл Назначение

bash

initramfs снабжает нас некой оболочкой на момент запуска.

mknod

Мы будем обладать способностью создания устройств. dracut применяет udev, некий движимый событиями инструмент, который будет запускать определённые программы, например, lvm, mdadm и т.д. при выполнении определённых правил udev. К примеру, когда выполнено соответствие неких правил udev, под /dev появятся тома хранения и файлы устройств сетевых карт.

kmod

Некий инструментарий управления имеющимися модулями ядра.

 

Сетевые исполняемые файлы

Существует доступным в 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

Таблица 5-2. Исполняемые файлы Systemd
Исполняемый файл Назначение

systemd

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

systemctl

Диспетчер службы systemd.

systemd-cgls

Будет перечислять существующие группы управления (cgroups, control groups).

systemd-escape

Преобразует получаемую строку в формат элемента systemd, также носящего название экранированного (escaped).

systemd-run

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

systemd-tmpfiles

Создаёт, удаляет и вычищает не постоянные и временные файлы и катоалоги.

journalctl

Некий инструмент, который имеет дело с журналом systemd.

Sbin

 

Исполняемые файлы файловой системы и относящиеся к хранению программы.

Таблица 5-3. Исполняемые файлы файловой системы и относящиеся к хранению программы.
Исполняемый файл Назначение

blkid

Считать атрибуты устройства.

chroot

Изменить устройство корневой текущей файловой системы.

e2fsck

Проверить файловые системы ext2/3/4.

fsck, fsck.ext4

Проверить и восстановить соответствующую файловую систему.

swapoff

Когда вы желаете остановить имеющееся устройство подкачки.

dmsetup

Инструмент установки соответствия для упраовления LVM.

dmeventd

Демеон событий соответствия устройств.

lvm

Инструмент управления LVM, который предоставляет команды lvscan, vgscan, vgchange, pvs и т.п..

lvm_scan

Сценарий поиска устройств LVM.

 

Сетевые исполняемые файлы

Таблица 5-4. Сетевые исполняемые файлы.
Исполняемый файл Назначение

dhclient

Для полусения IP от имеющегося сервера DHCP.

losetup

Для настройки устройства loop.

Netroot

Для поддержки root поверх установленной сетевой среды.

NetworkManager

Некий инструментарий управления имеющимися сетевыми устройствами.

 

Особые исполняемые файлы

Таблица 5-5. Специальные исполняемые файлы.
Исполняемый файл Назначение

depmod

Для генерации modules.dep (символической ссылки - symlink kmod).

lsmod

Для просмотра загруженных модулей (символической ссылки - symlink kmod).

modinfo

Для выдачи на печать сведений о модуле (символической ссылки - symlink kmod).

modprobe

Для загрузки или вставки модулей (символической ссылки - symlink kmod).

rmmod

Для удаления загруженного модуля (символической ссылки - symlink kmod).

init / systemd

Первый процесс.

kexec

kexec ядра, используемый Kdump.

udevadm

Диспетчер 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.

etc

Имеющиеся в каталогах 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, var

Как мы знаем, в эти дни 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
		

lib, lib64

Существует почти 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:

  1. Поскольку initramfs вступает некой корневой файловой системой (temporary), она создаст то окружение, которое требуется для запуска его процессов. initramfs будет смонтирована в качестве корневой файловой системы (временный /) и из неё будут запущены такие программы как systemd.

  2. После этого внутри временного каталога initramfs монтируется корневая файловая система некого нового пользователя с вашего HDD, либо из сетевой среды.

  3. После того как внутри initramfs смонтирована корневая файловая система этого пользователя, имеющееся ядро запустит установленный исполняемый файл init, который не что иное как символическая ссылка на systemd, самый первый процесс в нашей операционной системе.

    
    # ls init -l
    lrwxrwxrwx. 1 root root 23 Dec 21 12:19 init -> usr/lib/systemd/systemd
    		
  4. Если всё успешно, имеющаяся временная корневая файловая система (корневая файловая система 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 из памяти?

Задержимся на минутку чтобы попытаться восстановить всё что мы изучили на данный момент.

  1. Самым первым запускается начальный загрузчик.

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

  3. Ядро распаковывает себся самостоятельно.

  4. Наш начальный загрузчик передал значение местоположения initramfs в устанавливаемое ядро.

  5. Это ядро распаковывает в памяти initramfs.

  6. Из распакованного 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.

Как ядро монтирует initramfs в качестве корня?

Большой двоичный объект (blob) initramfs это просто некий файл cpio (возможно сжатый). Наше ядро распаковывает его создавая в памяти некую файловую систему tmpfs/ramfs. Поэтому на практике не существует некого фиксированного местоположения; Выделение памяти по мере распаковки выполняет само ядро. Мы уже отмечали, что наш начальный загрузчик GRUB 2 помещает загружаемое ядро в определённом местоположении, которое будет зависеть от архитектуры, однако распаковка образа initramfs не производится в каком- то определённом месте.

Теперь, прежде чем мы мы проследуем далее в своей последовательности запуска , нам требуется разобраться с имеющимся инструментарием dracut, который создаётся initramfs. Этот инструментарий снабдит нас лучшим пониманием initramfs и systemd.