BIOS отображает все найденные Option ROM на системную память
BIOS включает в таблицу IPL (до 16 записей)
встроенные устройства загрузки (BAID - BIOS Aware IPL Device, не имеют своей Option ROM) и инициализирует их как умеет
Option ROM (например, PCI Expansion ROM) должны иметь стандартный формат заголовка (сигнатура 55AAh) с заголовком расширения "$PnP"
(один Option ROM может иметь несколько заголовков расширения, каждый имеет контрольную сумму), который позволяет отнести устройства
к BEV (Bootstrap Entry Vector - смещение программы загрузки, например, контроллер Ethernet)
или BCV (Boot Connection Vector - смещение программы подключения, например, контроллер RAID;
может захватывать прерывания 9h (ввод), 10h (вывод) и 13h (диск));
также содержит идентификатор устройства, имя изготовителя, название продукта
(серийного номера не предусмотрено, поэтому в меню загрузки будет 8 одинаковых названий моделей диска),
тип устройства, подтип устройства, флажки (это устройство ввода, это устройство вывода, включить в IPL, прочее)
BIOS поочерёдно передаёт управление на вектор инициализации внутри заголовка
(переход, сегментная адресация - 16-bit Real Mode или 16-bit Protected Mode (16:16),
совместимый с адаптированными вызовами в 32-bit Protected Mode (16:32), совместимость с 0:32 Protected Mode (flat) не предполагалась)
каждого Option ROM (сначала видео, ввод и IPL);
инициализация не должна перехватывать прерывания 9h, 10h и 13h;
возвращает флажки: может обслуживать прерывания 9h (ввод), 10h (вывод) и 13h (диск), устройство готово к обслуживанию;
по ходу дела инициализируются требуемые шины и мосты;
программа инициализации BCV после включения устройства ищет подключённые устройства и для каждого добавляет заголовок BCV в памяти
и добавляет свой первый диск в список IPL
BIOS просматривает все Option ROM (в памяти) и ведёт таблицу BCV контроллеров с приоритетами BCV,
передаёт управление на сегментный адрес программы подключения (перехватывает прерывания 9h, 10h или 13h)
BIOS просматривает все Option ROM (в памяти) и определяет потенциальные загрузочные устройства из BEV и составляет таблицу IPL:
тип устройства, флажки (индекс последней загрузки в таблице, активное устройство, была ошибка, носитель готов),
сегментный адрес программы загрузки, строка описания ASCIIZ - имя продукта
приоритет загрузки определяется оператором при настройке BIOS и хранится в NVRAM (по умолчанию, сначала BAID, затем BEV устройства)
BIOS перебирает в соответствии с приоритетами загрузочные устройства из таблицы IPL и пытается с них загрузиться
(передаёт управление на сегментный адрес программы загрузки);
при неудаче программа загрузки должна выдать INT 18h (когда-то тут был BASIC)
программе загрузки передаётся номер загрузочного устройства (80h для первого НЖМД)
программа загрузки действует в зависимости от типа устройства:
блочное устройство: загрузка загрузочного сектора (512 байт) в память по адресу 0000:7C00h и передача ему управления;
если загрузка с жёсткого диска, то загрузочный сектор лежит в MBR (Master Boot Record)
первоначальный загрузчик находит и загружает программу загрузки 2 этапа
(stage 2) и передаёт ей управление (GRUB, LILO, SYSLINUX);
используется BIOS API; обычное место загрузчика 2 этапа - /boot/
загрузчик 2 этапа выбирает, находит и загружает ядро и RAM диск (initrd)
в память;
GRUB читает конфигурацию из /boot/grub/grub.conf;
конфигурация для LILO хранится в MBR;
GRUB и LILO позволяют вывести список возможных загружаемых систем
на экран и выбрать нужную с помощью клавиатуры;
GRUB позволяет изменить параметры загрузки (корневая файловая система,
ядро, RAM диск, параметры ядра) с помощью текстового редактора;
используется BIOS API;
RAM диск содержит образ файловой системы с модулями (драйверами)
устройств, необходимыми для монтирования корневой файловой системы;
в случае со встроенным Linux RAM диск содержит всю систему
ядро повторно обходит и инициализирует периферийные устройства,
для которых есть встроенные драйвера
ядро монтирует RAM диск (предварительно разжав) и загружает
с него необходимые модули,
инициализирует соответствующие устройства
если необходимо, то ядро инициализирует LVM и программный RAID
ядро размонтирует RAM диск и освобождает занимаемую им память
ядро монтирует корневую файловую систему в режиме "только чтение";
в процессе дальнейшей работы ядро загружает дополнительные модули
с корневой файловой системы
запускается процесс /sbin/init (далее описывается загрузка в стиле
System V)
init разбирает конфигурационный файл /etc/inittab
для определения дальнейших действий;
если при загрузке указан уровень s (или S), то inittab не читается,
а система переходит в однопользовательский режим (shell на
/dev/console с правами root);
строка с действием initdefault определяет
"уровень выполнения" (run level) по умолчанию, т.е. режим работы системы
(однопользовательская, многопользовательская, с доступом в сеть,
с графическим окружением и т.д.);
строка с действием sysinit (/etc/rc.d/rc.sysinit) определяет
скрипт инициализации;
init выполняет скрипт /etc/rc.d/rc.sysinit (проверка и монтирование
остальных файловых систем, swap и т.д.)
в "нормальном" /etc/inittab при переходе на любой уровень запускается
скрипт /etc/rc.d/rc с указанием уровня в качестве параметра;
данный скрипт запускает скрипты /etc/rcуровень.d/K*
(в алфавитном порядке) с параметром stop и скрипты
/etc/rcуровень.d/S* с параметром start;
в конце запускается /etc/rc.d/rc.local;
по традиции скрипты являются символьными ссылками
на скрипты в директории /etc/init.d/;
вместо /etc/init.d/ может использоваться /etc/rc.d/init.d/;
вместо /etc/rcуровень.d/ может использоваться /etc/rc.d/rcуровень.d;
реальность несколько сложнее
загрузка ядра и RAM диска;
RAM диск содержит образ файловой системы с модулями (драйверами)
устройств, необходимыми для монтирования корневой файловой системы;
в случае со встроенным Linux RAM диск содержит всю систему
ядро повторно обходит и инициализирует периферийные устройства, для которых есть встроенные драйвера
ядро монтирует RAM диск (предварительно разжав) и загружает с него необходимые модули,
инициализирует соответствующие устройства - dracut
ядро размонтирует RAM диск и освобождает занимаемую им память
ядро монтирует корневую файловую систему в режиме "только чтение";
в процессе дальнейшей работы ядро загружает дополнительные модули с корневой файловой системы
запускается процесс /usr/lib/systemd/systemd
тут будет длинный рассказ после того как systemd устоится
systemd (LGPL) - управление системой и сервисам.
RHEL/CentOS 7.9 - версия 219.
Запускается как PID 1 вместо initd (sysvinit). Для совместимости поддерживает скрипты инициализации LSB.
Управляет запуском модулей (unit) и отслеживает зависимость между модулями.
В будущем заменит собой все системные сервисы Linux. Уже имеется сервис журнализации (systemd-journal вместо syslog),
управление сеансами пользователей (systemd-logind вместо ConsoleKit), временем и сетевым временем (timedated и timesyncd вместо ntpd/chronyd),
именем хоста (вместо hostbame), именами DNS (systemd-resolved вместо библиотеки resolv), локалью (localed вместо ?),
контейнерами и виртуальными машинами (systemd-nspawn, machinectl, systemd-machined.service),
учётными записями, настройками, сетевыми интерфейсами (networkd, networkctl, /lib/systemd/network/ вместо network-scripts и nmcli),
монтированием (вместо /etc/fstab и mount) и монтированием по требованию (вместо automount), замена chroot
и UEFI загрузчику (systemd-boot), systemd-tmpfiles, systemd-udevd. Кстати, Gnome 3.8 и выше не работает без systemd.
Использует D-Bus, cgroups и Unix-сокеты для общения между процессами.
Контролирует состояние модулей и реагирует на их изменение.
Позволяет активировать сервисы по зависимостям, обращению к портам (замена inetd, xinetd.service?), по расписанию (замена cron).
Типы модулей
сервисы (.service) - набор процессов, изолируемых средствами cgroups
цель, режим работы (.target) - группа сервисов (аналог уровня initd)
точка монтирования (.mount)
точка монтирования по запросу (.automount)
раздел подкачки (.swap)
запуск других модулей по расписанию (.timer)
работа с сокетами (.socket)
контейнер cgroups (.slice)
подключение устройства (.device)
управление иерархией файловой системы (.path)
.snapshot
.scope
Основной файл настройки - /etc/systemd/system.conf (/etc/systemd/system/).
systemctl - утилита управления, systemd-analyze - трассировка загрузки.
systemctl - основная управляющая утилита systemd. Файл настройки - /etc/systemd/system.conf.
Список сервисов: systemctl [--all] [--state={active|failed}] {list-units|list-unit-files} [режим-работы].
Управление работой сервисов: systemctl {is-active|status|start|stop|reload|restart} имя-сервиса.
Управление запуском сервисов при загрузке: systemctl {disable|enable|preset} имя-сервиса.
Управление режимом работы (аналог уровня в inittab): systemctl set-default {graphical.target|multi-user.target|rescue.target}.
Ключ ядра systemd.unit=имя-режима. Сервис debug-shell обеспечивает оболочку во время загрузки (enable).
Перезапуск systemd: systemctl daemon-reload. Необходимо, например, при добавлении сервиса.
Перезагрузка: systemctl reboot [--firmware-setup].
7 Ctrl-Alt-Del в течении 2 секунд - немедленная перезагрузка.
Привычный /etc/rc.local лежит в /etc/rc.d/rc.local, настройки systemd сервиса rc-local расположены в /usr/lib/systemd/system/rc-local.service,
запускается в режиме multi-user.target после network.target, предварительно необходимо дать права на выполнение
chmod u+x /etc/rc.d/rc.local
Пример своего сервиса (/usr/lib/systemd/system/имя-сервиса.service):
LILO и GRUB работают через BIOS,
а большинство BIOS позволяют доступ только
к первым двум IDE-дискам (считая ATAPI CD-ROM) в пределах первых 1023 цилиндров.
Так что каталог (или раздел) /boot, в котором хранятся как файлы самого
загрузчика, так и загружаемые файлы (ядро, initrd) должен удовлетворять
данным ограничениям.
идентификатор - уникальная последовательность от 1 до 4 символов
(в старых версиях до 2); для getty и ему подобных идентификатор
д.б. номером линии tty
перечень-уровней-выполнения - перечисление (без пробела) уровней
выполнения, для которых выполняется указанное действие
(от 0 до 6 и от A до C, s, S); для sysinit, boot и bootwait
игнорируется; при смене уровня всем процессам, не специфицированным
для этого уровня, посылается сигнал SIGTERM, а через 5 секунд (интервал
задаётся при вызове telinit -t) сигнал SIGKILL
(init предполагает, что процесс не сменил группу процессов, в которой
он его запустил);
пустой список означает "для всех"
действие (по-моему, тут перемешанны условия и действия)
respawn (процесс по завершении запускается вновь и вновь;
после 10 перезапусков за 2 минуты делается пауза 5 минут)
wait (процесс запускается один раз при переходе на уровень,
init ждёт его завершения)
once (процесс запускается один раз при переходе на уровень)
boot (процесс запускается при загрузке системы)
bootwait (процесс запускается при загрузке системы,
init ждёт его завершения)
off (ничего не делать)
ondemand (процесс запускается при вызове данного уровня
выполнения (от A до C), но смены уровня не происходит)
initdefault (на какой уровень выполнения переходить после загрузки;
если не указан, то будет спрашивать на консоли)
sysinit (процесс запускается при загрузке до boot и bootwait)
powerwait (вызывается при пропадании питания, например, программой
слежения за UPS,
SIGPWR (подробности в /etc/powerstatus: FAIL),
init ждёт его завершения)
powerfail (вызывается при пропадании питания, например, программой
слежения за UPS,
SIGPWR (подробности в /etc/powerstatus: FAIL),
init не ждёт его завершения)
powerokwait (вызывается при возобновлении питания,
SIGPWR (подробности в /etc/powerstatus: OK),
init ждёт его завершения)
powerfailnow (вызывается непосредственно перед исчерпанием
аккумуляторов UPS, SIGPWR (подробности в /etc/powerstatus: LOW))
ctrlaltdel (вызывается при получении сигнала SIGINT от ядра)
kbrequest (ядро посылает SIGWINCH при нажатии определённой
комбинации клавиш)
процесс - имя файла ('+' перед символом отменяет запись utmp и wtmp),
программа или скрипт
При запуске процесса устанавливаются переменные окружения:
PATH, INIT_VERSION, RUNLEVEL, PREVLEVEL, CONSOLE.
Уровни выполнения для Red Hat Linux:
0: halt (неинтереактивный уровень)
1: single user (одна виртуальная консоль)
2: multiuser (6 виртуальных консолей)
3: multiuser + NFS (6 виртуальных консолей)
4: не используется
5: X11 (6 виртуальных консолей и xdm, gdm или kdm
в зависимости от /etc/X11/prefdm)
6: reboot (неинтереактивный уровень)
Переход на другой уровень можно сделать с помощью
программы telinit или прямо через /dev/initctl.
telinit с указанием уровня q (Q) заставляет init
перечитать /etc/inittab. Использование SIGPWR и /etc/powerstatus признано
устаревшим.
Загрузчик может передать процессу init параметры
-s, S, single (загрузка в однопользовательском режиме)
от 1 до 5 (явное задание уровня выполнения)
-b, emergency (однопользовательский режим без выполнения sysinit)