- Трек на suno по загрузке Linux 🙂
- BIOS – Basic Input/Output System
- UEFI – Unified Extensible Firmware Interface
- Общий процесс загрузки Linux, подробнее отдельно ниже
- И BIOS и UEFI имеют уязвимости, но сейчас на слуху именно уязвимости UEFI
Аналитики компании Binarly обнаружили 23 критические уязвимости в UEFI от InsydeH2O, которая используется многими крупными вендорами, включая HP, Lenovo, Fujitsu, Microsoft, Intel, Dell, Bull (Atos) и Siemens.
- В BIOS есть настройки работы с питанием (bios power management), могут быть полезны:
- что делать в случае неожиданного отключения
- не включаться (по умолчанию)
- включать сразу
- включаться всегда при наличии питания
- что делать в случае неожиданного отключения
- Правки дампа BIOS делаются
- (чаще работает) с использованием HEX редактора и UEFITool – дамп BIOS открывается в UEFITool, ищется модуль, содержащий необходимые для замены значения, экпортируется, изменяется в HEX редакторе, импортируется, сохраняется новый образ и при помощи программатора заливается на микросхему
- (чаще не работает) с использованием HEX редактора – дамп BIOS открывается в HEX редакторе, далее ищутся строки которые необходимо заменить, дамп сохраняется и при помощи программатора заливается на микросхему
BOOT directory
В Boot директории содержатся ключевые файлы, необходимые для загрузки системы – grub.cfg, kernel, boot image, initrd/initramfs, config и прочие.
[root@localhost ~]# ll /boot/ total 108556 -rw-r--r--. 1 root root 126426 Nov 20 2015 config-3.10.0-327.el7.x86_64 drwxr-xr-x. 2 root root 4096 Oct 11 11:07 extlinux drwxr-xr-x. 2 root root 26 Jul 27 17:23 grub drwx------. 6 root root 104 Jul 27 21:05 grub2 -rw-r--r--. 1 root root 57594234 Jul 27 20:32 initramfs-0-rescue-c45de976bcc44afba871f946c3230751.img -rw-r--r--. 1 root root 29701379 Jul 27 21:03 initramfs-3.10.0-327.el7.x86_64.img -rw-r--r--. 1 root root 10192063 Jul 27 20:01 initrd-plymouth.img -rw-r--r--. 1 root root 252612 Nov 20 2015 symvers-3.10.0-327.el7.x86_64.gz -rw-------. 1 root root 2963044 Nov 20 2015 System.map-3.10.0-327.el7.x86_64 -rwxr-xr-x. 1 root root 5156528 Jul 27 20:41 vmlinuz-0-rescue-c45de976bcc44afba871f946c3230751 -rwxr-xr-x. 1 root root 5156528 Nov 20 2015 vmlinuz-3.10.0-327.el7.x86_64
[root@localhost ~]# ll /boot/grub2 total 32 -rw-r--r--. 1 root root 64 Jul 27 20:51 device.map drwxr-xr-x. 2 root root 24 Jul 27 20:51 fonts -rw-r--r--. 1 root root 4231 Jul 27 21:05 grub.cfg -rw-r--r--. 1 root root 1024 Oct 17 18:56 grubenv drwxr-xr-x. 2 root root 8192 Jul 27 20:51 i386-pc drwxr-xr-x. 2 root root 4096 Jul 27 20:51 locale drwxr-xr-x. 3 root root 19 Jul 27 17:59 themes
Процесс загрузки Linux
-
- запуск микрокода BIOS / UEFI который проверяет hardware (POST – Power-on self-test), осуществляет его низкоуровневую настройку, определяет на каком носителе будет осуществляться поиск загрузчика и выполняет программу-загрузчик ОС, как только загрузчик был обнаружен и загружен в память, BIOS передает управление ему.
- /boot/efi (папка может быть пустой): поиск на выбранном носителе главная загрузочной записи MBR / GPT (чаще всего сформатированном в небольшой раздел FAT32) загрузчика bootloader в boot record носителя (первые секторы раздела носителя) – именно для создания boot record на носителях (flash/usb) нужно использовать dd / rufus / unetbooting / win32diskimager и прочие утилиты, недостаточно просто ‘забросить’ файлы на носитель. MBR размещена в 1-м секторе загрузочного диска, например /dev/hda или /dev/sda. MBR занимает меньше, чем 512 байтов. Она содержит информацию о GRUB’е (или LILO) и состоит из трех компонентов:
- главная загрузочная информация, «живущая» в первых 446 байтах
- информация о таблице разделов — в следующих 64 байтах
- последние 2 байта нужны для проверки корректности mbr
- boot/grub (тут или в /boot/grub/ или в /etc/ находится файл конфигурации grub.conf/grub.cfg): запуск bootloader (сейчас обычно в виде GRUB version 2, но раньше были разные bootloader, что привело к созданию GRand Unified Bootloader – универсального загрузчика для разных ОС/разных ядер одной ОС, который может или полностью подменить существующий загрузчик или «встать» перед ним как в случае с Windows); ключевое что содержит GRUB это местонахождение файлов с ОС на диске (путь к ядру и образу initrd), но так же в конфигурации GRUB можно задать доп. параметры типа kernel parameters в /proc/cmdline, параметры recovery feature, можно отключать аппаратные и програмные модули еще до загрузки ОС и даже управлять разрешением экрана (для извращений).
- Пример записи из GRUB для одной из menuentry, в конфиге grub можно указать конкретные ядра/список ядер:
- menuentry ‘Debian GNU/Linux, with Linux 4.19.0-9-amd64 (recovery mode)’
- linux /boot/vmlinuz-4.19.0-9-amd64 – kernel
- initrd /boot/initrd.img-4.19.0-9-amd64 – RAM disk
- menuentry ‘Debian GNU/Linux, with Linux 4.19.0-9-amd64 (recovery mode)’
- Для автоматического редактирования grub файла в случае обновления ядра делать ничего вручную не нужно – автоматически установщик добавляет menu entry с новым ядром и метит его дефолтным для загрузки, пример описан в CentOS
- Для редактирования grub нужно не редактировать сам grub файл (он находится в boot и обычно эта директория read only), а редактировать файл grub в директории /etc/default через sudoedit; на случай проблем рекомендуется иметь live USB, с которого можно загрузиться и пофиксить конфигурацию GRUB
- sudoedit /etc/default/grub
- Пример опций/изменений, хорошо описаны на gnu.org
- GRUB_TIMEOUT=5 – сколько будет timeout ожидания выбора ОС/ядра (-1 бесконечно, 0 не ждать вообще)
- GRUB_DISABLE_RECOVERY=true – режимы восстановления не показываются в меню GRUB
- GRUB_DEFAULT=saved – сохранение выбранной опции в последней загрузке (выбранной ОС) по умолчанию
- GRUB_DEFAULT=”1>Debian GNU/Linux, with Linux 4.19.0-20-amd64″ – фиксация конкретной версии ядра Linux
- GRUB_TERMINAL_OUTPUT=console – может быть изменение с вывода на консоль в другой источник – напр. на serial port для сетевых девайсов в среднем может быть лучше т.к. монитор для подключения к консоли может отсутствовать
- GRUB_CMDLINE_LINUX=”default_hugepagesz=1GB hugepagesz=1G hugepages=8 transparent_hugepage=never” – пример настройки huge pages для DPDK/TRex
- GRUB_CMDLINE_LINUX=”isolcpus=1-19″ – пример изоляции CPU ядер
- Кроме основного файла grub.cfg, GRUB так же считывает все конфигурационные файлы из директории /etc/grub.d и добавляет их в общую конфигурацию grub в один grub.cfg; изменения пользователя в виде кастомизированный меню-записей рекомендуется добавлять в файлы 40_custom, другую кастомазацию 41_custom, найденые ОС, добавленные в меню фигурируют в 30_os-prober
- Пример записи из GRUB для одной из menuentry, в конфиге grub можно указать конкретные ядра/список ядер:
/etc/grub.d# ls -ltr total 76 -rwxr-xr-x 1 root root 6258 Jun 13 2019 05_debian_theme -rw-r--r-- 1 root root 483 Jun 25 2019 README -rwxr-xr-x 1 root root 216 Jun 25 2019 41_custom -rwxr-xr-x 1 root root 214 Jun 25 2019 40_custom -rwxr-xr-x 1 root root 1418 Jun 25 2019 30_uefi-firmware -rwxr-xr-x 1 root root 12059 Jun 25 2019 30_os-prober -rwxr-xr-x 1 root root 11497 Jun 25 2019 20_linux_xen -rwxr-xr-x 1 root root 12444 Jun 25 2019 10_linux -rwxr-xr-x 1 root root 9783 Jun 25 2019 00_header
-
-
- Обновление конфигурации GRUB после изменений, при обновлении GRUB собирает все файлы конфигурационные файлы в один grub.cfg, проверяет корректность синтаксиса перед обновлением конфигурации в /boot/ директории
- sudo update-grub или sudo update-grub2 – Debian
- sudo grub2-mkconfig -o /boot/grub2/grub.cfg – RHEL
- Обновление конфигурации GRUB после изменений, при обновлении GRUB собирает все файлы конфигурационные файлы в один grub.cfg, проверяет корректность синтаксиса перед обновлением конфигурации в /boot/ директории
- boot/initrd.img / initramfs.img (обычно линк к конкретному файлу определенной версии ядра):
- ядро ОС монтирует ram disk initrd/initramfs. Initrd (Initial RAM Disk) – временный диск в оперативной памяти; в виде образа диска копируется в RAM и рассматривается как полноценный примонтированный hard drive диск, внутри initrd находится код ОС, который необходим для старта системы. initrd используется самим ядром в качестве временной корневой файловой системы, пока kernel не загрузится в реальную примонтированную файловую систему. Этот временный диск также содержит необходимые для загрузки драйверы, позволяющие получить доступ к разделам дисков и другому оборудованию.
- ядро ОС запускает код операционной системы через выполнение программы /sbin/init. Поскольку init — это первый процесс, запущенный ядром Linux, поэтому она имеет идентификатор процесса (PID) №1
- /sbin/init (обычно линк к /lib/systemd/systemd): код ядра запускает init процесс/скрипт, который в свою очередь отвечает за запуск всех остальных компонентов/сервисов/приложений системы, вариантов реализации init несколько, ключевые:
-
- systemd – самый новый и популярный, работает в виде отдельного процесса
- sysvinit (old from unix) – самый старый, работает в виде скриптов
- upstart (backward compatible with sysvinit)
-
-
Initrd (сокращение от англ. Initial RAM Disk, диск в оперативной памяти для начальной инициализации) — временная файловая система, используемая ядром Linux при начальной загрузке. Initrd обычно используется для начальной инициализации перед монтированием «настоящих» файловых систем. В Linux Kernel HOWTO (руководстве о сборке ядра) пишут, что initrd призван решить проблему курицы и яйца для модульного ядра: для монтирования файловой системы необходим модуль для работы с диском и файловой системой, а для чтения модуля необходима файловая система, с которой этот модуль читается[1].
runlevel – исходя из настроек по умолчанию с указанием номера runlevel, система будет выполнять файлы в соответствии с нижеприведенными директориями, соответствующими runlevel. К примеру, это могут быть сообщения типа «starting Postfix … OK» (запускается Postfix). Эти службы — и называются программами уровня выполнения, выполняемые из директории, которая соответствует нужному уровню выполнения.
Выполнение уровня 0 – /etc/rc.d/rc0.d/ Выполнение уровня 1 – /etc/rc.d/rc1.d/ Выполнение уровня 2 – /etc/rc.d/rc2.d/ Выполнение уровня 3 – /etc/rc.d/rc3.d/ Выполнение уровня 4 – /etc/rc.d/rc4.d/ Выполнение уровня 5 – /etc/rc.d/rc5.d/ Выполнение уровня 6 – /etc/rc.d/rc6.d/ Чаще всего тут используются ссылки типо: # ls -ltr /etc/rc2.d/ total 0 lrwxrwxrwx 1 root root 14 May 24 2021 S01cron -> ../init.d/cron
В каталогах вы можете увидеть список программ, имя которых начинается из букв S и K.
-
- Программы, начинающиеся на S используются для запуска. S, потому что startup.
- Программы, которые начинаются с литеры K используются — правильно — для завершения работы. K, потому что kill.
- Еще есть номера рядом с буквами S и K в именах программ. Эти номера используются для определения порядка запуска этих программ.
К примеру, - S12syslog предназначен для запуска демона syslog, его порядковый номер 12. - S80sendmail — для запуска демона sendmail, имеющего порядковый номер 80. Таким образом, программа syslog будет запущена перед sendmail. По факту сейчас в Debian так: # ls -ltr /etc/rc5.d/ total 0 lrwxrwxrwx 1 root root 14 May 24 2021 S01cron -> ../init.d/cron lrwxrwxrwx 1 root root 17 May 24 2021 S01rsyslog -> ../init.d/rsyslog lrwxrwxrwx 1 root root 26 May 24 2021 S01console-setup.sh -> ../init.d/console-setup.sh lrwxrwxrwx 1 root root 14 May 24 2021 S01dbus -> ../init.d/dbus lrwxrwxrwx 1 root root 13 May 24 2021 S01ssh -> ../init.d/ssh lrwxrwxrwx 1 root root 15 Mar 14 2022 S01squid -> ../init.d/squid lrwxrwxrwx 1 root root 14 Sep 29 2023 S01atop -> ../init.d/atop lrwxrwxrwx 1 root root 18 Sep 29 2023 S01atopacct -> ../init.d/atopacct
runlevel+sysvinit: На старых системах под управлением sysvinit используется файл /etc/inittab для того, чтобы определить уровень выполнения (runlevel). Init определяет уровень выполнения по умолчанию (initdefault) и использует его для загрузки всех необходимых программ.
Есть следующие уровни выполнения: 0 – прервать выполнение 1 – однопользовательский режим, так называемый «Single user mode», или иными словами, консоль восстановления 2 – многопользовательский режим без поддержки NFS 3 – полноценный многопользовательский режим 4 – не используется 5 – X11 6 – перезагрузка
runlevel+systemd: На более актуальных системах с управлением systemd файл /etc/inittab не используется, runlevel задается в конфигурации systemd, уровни приближенные к старым, но в целом они могут отличаться в разных дистрибутивах.
root@serv:~# systemctl get-default graphical.target root@serv:~# runlevel N 5 root@serv:~# ls -la /lib/systemd/system/runlevel* lrwxrwxrwx 1 root root 15 Mar 18 2021 /lib/systemd/system/runlevel0.target -> poweroff.target lrwxrwxrwx 1 root root 13 Mar 18 2021 /lib/systemd/system/runlevel1.target -> rescue.target lrwxrwxrwx 1 root root 17 Mar 18 2021 /lib/systemd/system/runlevel2.target -> multi-user.target lrwxrwxrwx 1 root root 17 Mar 18 2021 /lib/systemd/system/runlevel3.target -> multi-user.target lrwxrwxrwx 1 root root 17 Mar 18 2021 /lib/systemd/system/runlevel4.target -> multi-user.target lrwxrwxrwx 1 root root 16 Mar 18 2021 /lib/systemd/system/runlevel5.target -> graphical.target lrwxrwxrwx 1 root root 13 Mar 18 2021 /lib/systemd/system/runlevel6.target -> reboot.target