Загрузка операционной системы, это многоступенчатый процесс. В различных дистрибутивах Linux процесс загрузки может несколько изменяться, но общая схема примерно одинакова и состоит из следующих стадий:
В момент запуска процессор передаёт управление по определённому физическому адресу в ПЗУ. В этот момент начинается выполнение кода BIOS/UEFI. Производится инициализация оборудования и выбирается загрузочный носитель. В случае BIOS происходит считывание в ОЗУ начального загрузчика и передача управления на него. Начальный загрузчик обычно занимает один сектор на диске (MBR) и ограничен размером 384 байт ( 512 байт – сектор диска, минус 128 байт – таблица разделов). В зависимости от типа загрузочного устройства загрузочный сектор может считываться из разных мест:
При форматировании диска в MBR вместо загрузчика иногда пишется программа, которая пишет на экране информационный текст "No bootable device -- insert boot disk and prress any key"
1.1 Начальный загрузчик считывает в память основной загрузчик (GRUB, LiLo, NTLDR) и передаёт управление ему. Поскольку начальный загрузчик очень мал, то, как правило, в его код жестко прописывают сектора, из которых надо прочитать код основного загрузчика. На HDD это может быть пространство между MBR и первым разделом на диске (нулевая дорожка) или зарезервированное место внутри ФС (зарезервированный Inode в ext2fs). На дискете и при использовании образа диска при загрузке с CD или по сети – основной загрузчик может располагаться сразу вслед за первичным загрузчиком и занимать весь объём образа.
При загрузке через UEFI загрузчик или непосредственно ядро Linux считывается целиком из файла на системном разделе EFI с файловой системой FAT32.
Загрузка ядра (vmlinuz) и вспомогательного образа диска (initrd, initramfs). Загрузчик GRUB представляет из себя мини ОС, поддерживающую все основные файловые системы. GRUB ищет конфигурационный файл, в котором прописаны пути к образу ядра и образу вспомогательного диска. При необходимости образ ядра распаковывается в ОЗУ, формируется область памяти, содержащая параметры, передаваемые из загрузчика в ядро, в том числе адрес образа вспомогательного диска.
Ядро загружаемое через GRUB должно соответствовать соглашениям multiboot или multiboot2 . В соответствии с соглашением, образ ядра включает структуру (например в секции данных), которая начинается с магического числа и содержит информацию о желаемом положении ядра в памяти и точке на которую надо передать управление. Перед передачей управления в ядро в регистр EAX помещается ещё одно магическое число, а в регистр EBX - адрес таблицы с параметрами, подготовленными загрузчиком.
Вспомогательный диск необходим современным Linux системам из-за модульности ядра и содержит драйверы (ATA, NFS, RAID и т.п.), необходимые для получения доступа к основной файловой системе. Внутри образа находится файловая система в формате архива cpio.
На этом этапе создаётся процесс с pid=1
, в котором происходит выполнение скрипта init
, находящегося в корневом каталоге вспомогательного диска. Параметры, передаваемые ядру, фактически передаются в init
, как аргументы командной строки.
Скрипт содержит команды загрузки необходимых драйверов в виде модулей ядра, создание временных файлов устройств в каталоге /dev
для доступа к этим модулям, сканирование дисковых разделов для обнаружения и инициализации RAIDов и логических томов. После инициализации логических дисков, делается попытка смонтировать корневую файловую систему, заданную параметром root=
. В случае бездисковой сетевой загрузки корневой каталог подключается по NFS.
На экран выдаются сообщения о загрузке драйверов и о поиске виртуальных томов подсистемы LVM. Этап завершается перемонтированием корневого каталога на основную файловую систему и загрузку в процесс с pid=1
основной программы /sbin/init
(или её аналога).
В классическом UNIX'е и старых версиях Linux (примерно до 2012 года) программа init
считывает конфигурационный файл /etc/inittab
, инициализирует текстовые консоли и, как правило, запускает необходимые службы с помощью набора скриптов, расположенных в каталогах /etc/init.d
и /etc/rc*.d
. В современных дистрибутивах Linux в файле /sbin/init
находится более современная программа запуска служб. Наиболее популярной из подобных программ является systemd
, который позволяют существенно сократить время этого этапа загрузки.
На экран на этом этапе выдаются строки, сообщающие о запуске служб, и информация об успешности данного процесса ([OK] или [ERR]).