# Процесс загрузки системы

Когда компьютер включается, первое программное обеспечение, которое запускается, — это загрузчик. Это фрагмент кода, единственной целью которого является загрузка ядра операционной системы и передача ему управления. Ядро загрузит необходимые драйверы, инициализирует аппаратное обеспечение, а затем загрузит остальную часть операционной системы.

GRUB — это загрузчик, используемый в большинстве дистрибутивов Linux. Он может загружать ядро ​​Linux или другие операционные системы, такие как Windows, и может обрабатывать несколько образов и параметров ядра в виде отдельных пунктов меню. Выбор ядра при загрузке осуществляется через интерфейс, управляемый клавиатурой, и есть интерфейс командной строки для редактирования параметров и параметров загрузки.

Большинство дистрибутивов Linux устанавливают и настраивают GRUB (на самом деле, GRUB 2) автоматически, поэтому обычному пользователю не нужно об этом думать. Однако для системного администратора очень важно знать, как управлять процессом загрузки, чтобы вы могли восстановить систему после сбоя загрузки, например, после неудачного обновления ядра.
В этом уроке вы узнаете, как установить, настроить и взаимодействовать с GRUB.

# Загрузчик

Исторически жесткие диски в системах, совместимых с IBM PC, были разбиты на разделы с использованием схемы разделения MBR, созданной в 1982 году для IBM PC-DOS (MS-DOS) 2.0.

В этой схеме первый 512-байтовый сектор диска называется основной загрузочной записью и содержит таблицу, описывающую разделы на диске (таблицу разделов), а также код начальной загрузки, называемый загрузчиком.

Когда компьютер включен, этот самый минимальный (из-за ограничений по размеру) код загрузчика загружается, выполняется и передает управление вторичному загрузчику на диске, обычно расположенному в пространстве 32 КБ между MBR и первым разделом, который в очередь загрузит операционную систему(ы).

На диске с разделами MBR загрузочный код для GRUB устанавливается в MBR. Это загружает и передает управление «базовому» образу, установленному между MBR и первым разделом. С этого момента GRUB может загружать остальные необходимые ресурсы (определения меню, файлы конфигурации и дополнительные модули) с диска.

Однако MBR имеет ограничения на количество разделов (первоначально максимум 4 основных раздела, позже максимум 3 основных раздела с 1 расширенным разделом, разделенным на несколько логических разделов) и максимальный размер диска 2 ТБ. Для преодоления этих ограничений была создана новая схема разбиения под названием GPT (таблица разделов GUID), которая является частью стандарта UEFI (унифицированный расширяемый интерфейс прошивки).

Диски с разделами GPT можно использовать как с компьютерами с традиционной BIOS ПК, так и с прошивкой UEFI. На машинах с BIOS вторая часть GRUB хранится в специальном загрузочном разделе BIOS.

В системах с прошивкой UEFI GRUB загружается прошивкой из файлов grubia32.efi (для 32-битных систем) или grubx64.efi (для 64-битных систем) из раздела под названием ESP (EFI System Partition).

## Загрузочный раздел /boot

В Linux файлы, необходимые для процесса загрузки, обычно хранятся в загрузочном разделе, монтируются в корневой файловой системе и в просторечии называются `/boot`.

Загрузочный раздел не требуется в текущих системах, поскольку загрузчики, такие как GRUB, обычно могут монтировать корневую файловую систему и искать необходимые файлы в каталоге `/boot`. Это хорошая практика, поскольку она разделяет файлы, необходимые для процесса загрузки от остальной файловой системы.

Этот раздел обычно является первым на диске. Это связано с тем, что исходный BIOS IBM PC адресовал диски с использованием цилиндров, головок и секторов (CHS), максимум 1024 цилиндра, 256 головок и 63 сектора, в результате чего максимальный размер диска составлял 528 МБ (504 МБ в MS-DOS). . Это означает, что все, что находится за этой отметкой, будет недоступно, если только не будет использована другая схема адресации диска (например, LBA, адресация логических блоков).

Поэтому для максимальной совместимости раздел `/boot` обычно располагается в начале диска и заканчивается до цилиндра 1024 (528 МБ), что гарантирует, что машина всегда сможет загрузить ядро. Рекомендуемый размер этого раздела на текущем компьютере — 300 МБ.

Другими причинами для отдельного раздела `/boot` являются шифрование и сжатие, поскольку некоторые методы могут еще не поддерживаться GRUB 2, или если вам необходимо отформатировать системный корневой раздел (/) с использованием неподдерживаемой файловой системы.

## Содержимое загрузочного раздела

Содержимое раздела /boot может различаться в зависимости от архитектуры системы или используемого загрузчика, но в системе на базе x86 вы обычно найдете файлы, указанные ниже. Большинство из них имеют суффикс -VERSION, где -VERSION — это версия соответствующего ядра Linux. Так, например, файл конфигурации ядра Linux версии 4.15.0-65-generic будет называться config-4.15.0-65-generic.

### - файл конфигурации

Этот файл, обычно называемый config-VERSION (см. пример выше), хранит параметры конфигурации ядра Linux. Этот файл генерируется автоматически при компиляции или установке нового ядра и не должен изменяться пользователем напрямую.

### - карта системы

Этот файл представляет собой справочную таблицу, сопоставляющую имена символов (таких как переменные или функции) с их соответствующей позицией в памяти. Это полезно при отладке системного сбоя, известного как паника ядра, поскольку позволяет пользователю узнать, какая переменная или функция вызывалась в момент возникновения сбоя. Как и файл конфигурации, имя обычно System.map-VERSION (например, System.map-4.15.0-65-generic).

### - ядро 

Это собственно ядро ​​операционной системы. Имя обычно vmlinux-VERSION (например, vmlinux-4.15.0-65-generic). Вы также можете найти имя vmlinuz вместо vmlinux, z в конце означает, что файл был сжат.

### - начальный RAM-диск

Обычно он называется initrd.img-VERSION и содержит минимальную корневую файловую систему, загруженную на RAM-диск, содержащую утилиты и модули ядра, необходимые для того, чтобы ядро ​​могло смонтировать настоящую корневую файловую систему.

### - файлы, связанные с загрузчиком

В системах с установленным GRUB они обычно находятся в /boot/grub и включают файл конфигурации GRUB (/boot/grub/grub.cfg для GRUB 2 или /boot/grub/menu.lst в случае GRUB Legacy), модули (в /boot/grub/i386-pc), файлы перевода (в /boot/grub/locale) и шрифты (в /boot/grub/fonts).

## Установка GRUB 2

GRUB 2 можно установить с помощью утилиты grub-install. Если у вас система не загружается, вам нужно будет загрузиться с Live CD или аварийного диска, узнать, какой раздел является загрузочным для вашей системы, смонтировать его и затем запустить утилиту.

## Примечание

Приведенные ниже команды предполагают, что вы вошли в систему как root. Если нет, сначала запустите `sudo su — `чтобы «стать» root. Когда закончите, введите exit, чтобы выйти из системы и вернуться к обычному пользователю.

Первый диск в системе обычно является загрузочным устройством, и вам может понадобиться узнать, есть ли на диске загрузочный раздел. Это можно сделать с помощью утилиты `fdisk`. Чтобы вывести список всех разделов на первом диске вашей машины, используйте:

```
# fdisk -l /dev/sda
Disk /dev/sda: 111,8 GiB, 120034123776 bytes, 234441648 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x97f8fef5

Device     Boot    Start       End   Sectors   Size Id Type
/dev/sda1  *        2048   2000895   1998848   976M 83 Linux
/dev/sda2        2002942 234440703 232437762 110,9G  5 Extended
/dev/sda5        2002944  18008063  16005120   7,6G 82 Linux swap / Solaris
/dev/sda6       18010112 234440703 216430592 103,2G 83 Linux
```

Загрузочный раздел обозначается знаком * под загрузочным столбцом. В приведенном выше примере это /dev/sda1.

Теперь создайте временный каталог в /mnt и смонтируйте под ним раздел:

```
# mkdir /mnt/tmp
# mount /dev/sda1 /mnt/tmp
```

Затем запустите grub-install, указав загрузочное устройство (не раздел) и каталог, в который смонтирован загрузочный раздел. Если в вашей системе есть выделенный загрузочный раздел, введите следующую команду:

```
# grub-install --boot-directory=/mnt/tmp /dev/sda
```

Если вы устанавливаете в систему, в которой нет загрузочного раздела, а есть только каталог `/boot` в корневой файловой системе, укажите на него grub-install. Итак, команда:
```
# grub-install --boot-directory=/boot /dev/sda
```

# Настройка GRUB 2

Файл конфигурации по умолчанию для GRUB 2 — `/boot/grub/grub.cfg`. Этот файл создается автоматически, и ручное редактирование не рекомендуется. Чтобы внести изменения в конфигурацию GRUB, вам нужно отредактировать файл `/etc/default/grub`, а затем запустить утилиту update-grub для создания соответствующего файла.

`update-grub` обычно является ярлыком для `grub-mkconfig -o /boot/grub/grub.cfg`, поэтому они дают одинаковые результаты.

В файле `/etc/default/grub` есть несколько параметров, которые управляют поведением GRUB 2, например загрузка ядра по умолчанию, время ожидания, дополнительные параметры командной строки и т. д. Наиболее важными из них являются:

### GRUB_DEFAULT=

Пункт меню по умолчанию для загрузки. Это может быть числовое значение (например, 0, 1 и т. д.), имя пункта меню (например, debian) или сохраненное значение, которое используется в сочетании с GRUB_SAVEDEFAULT=, как описано ниже. Имейте в виду, что пункты меню начинаются с нуля, поэтому первый пункт меню равен 0, второй — 1 и т. д.

### GRUB_SAVEDEFAULT=

Если для этого параметра установлено значение true, а для GRUB_DEFAULT= установлено значение save, то параметр загрузки по умолчанию всегда будет последним, выбранным в меню загрузки.

### GRUB_TIMEOUT=

Время ожидания в секундах до выбора пункта меню по умолчанию. Если установлено значение 0, система загрузит запись по умолчанию без отображения меню. Если установлено значение -1, система будет ждать, пока пользователь не выберет опцию, независимо от того, сколько времени это займет.

### GRUB_CMDLINE_LINUX=

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

### GRUB_CMDLINE_LINUX_DEFAULT=

По умолчанию для каждого ядра Linux создаются две записи меню, одна с параметрами по умолчанию и одна запись для восстановления. С помощью этой опции вы можете добавить дополнительные параметры, которые будут добавлены только к записи по умолчанию.

### GRUB_ENABLE_CRYPTODISK=

Если установлено значение y, такие команды, как grub-mkconfig, update-grub и grub-install, будут искать зашифрованные диски и добавлять команды, необходимые для доступа к ним во время загрузки. Это отключает автоматическую загрузку (GRUB_TIMEOUT= с любым значением, кроме -1), потому что для расшифровки дисков перед доступом к ним требуется парольная фраза.

## Управление пунктами меню

Когда update-grub запускается, GRUB 2 сканирует ядра и операционные системы на машине и создает соответствующие записи меню в файле /boot/grub/grub.cfg. Новые записи можно вручную добавить в файлы сценариев в каталоге /etc/grub.d.

Эти файлы должны быть исполняемыми и обрабатываются update-grub по порядку номеров. Поэтому 05_debian_theme обрабатывается до 10_linux и так далее. Элементы пользовательского меню обычно добавляются в файл 40_custom.

Основной синтаксис для входа в меню показан ниже:

```
пункт меню "ОС по умолчанию" {
    установить корень = (hd0,1)
    linux /vmlinuz root=/dev/sda1 ro quiet splash
    initrd /initrd.img
}
```

Первая строка всегда начинается с `menuentry` и заканчивается `{`. Текст между кавычками будет отображаться как метка входа в меню загрузки GRUB 2.

Параметр set root определяет диск и раздел, где находится корневая файловая система операционной системы. Обратите внимание, что в GRUB 2 диски нумеруются с нуля, поэтому hd0 является первым диском.

k (sda под линуксом), hd1 второй и так далее. Однако нумерация разделов начинается с единицы. В приведенном выше примере корневая файловая система расположена на первом диске (hd0), первом разделе (,1) или sda1.

Вместо прямого указания устройства и раздела вы также можете использовать GRUB 2 для поиска файловой системы с определенной меткой или UUID (универсальным уникальным идентификатором). Для этого используйте параметр поиска `--set=root`, за которым следует параметр --label и метка файловой системы для поиска, или `--fs-uuid`, за которым следует UUID файловой системы.

Вы можете найти UUID файловой системы с помощью команды ниже:
```
$ ls -l /dev/disk/by-uuid/
total 0
lrwxrwxrwx 1 root root 10 nov  4 08:40 3e0b34e2-949c-43f2-90b0-25454ac1595d -> ../../sda5
lrwxrwxrwx 1 root root 10 nov  4 08:40 428e35ee-5ad5-4dcb-adca-539aba6c2d84 -> ../../sda6
lrwxrwxrwx 1 root root 10 nov  5 19:10 56C11DCC5D2E1334 -> ../../sdb1
lrwxrwxrwx 1 root root 10 nov  4 08:40 ae71b214-0aec-48e8-80b2-090b6986b625 -> ../../sda1
```

В приведенном выше примере UUID для /`dev/sda1` — это `ae71b214-0aec-48e8-80b2-090b6986b625`. Если вы хотите установить его в качестве корневого устройства для GRUB 2, введите команду 
```
search --set=root --fs-uuid ae71b214-0aec-48e8-80b2-090b6986b625
```

При использовании команды поиска обычно добавляется параметр `--no-floppy`, чтобы GRUB не тратил время на поиск на гибких дисках.

Строка linux указывает, где находится ядро ​​для операционной системы (в данном случае это файл vmlinuz в корне файловой системы). После этого вы можете передать параметры командной строки ядру.

В приведенном выше примере мы указали корневой раздел (`root=/dev/sda1`) и передали три параметра ядра: корневой раздел должен быть смонтирован только для чтения (`ro`), большинство сообщений журнала должны быть отключены (`quiet`) и экран заставки должен быть показан (`splash`).

Строка `initrd` указывает, где находится начальный RAM-диск. В приведенном выше примере это файл `initrd.img`, расположенный в корне файловой системы.

Большинство дистрибутивов Linux на самом деле не помещают ядро ​​и `initrd` в корневой каталог корневой файловой системы. Вместо этого это ссылки на реальные файлы внутри каталога или раздела `/boot`.

Последняя строка пункта меню должна содержать только символ `}`.

## Взаимодействие с GRUB 2

При загрузке системы с GRUB 2 вы увидите меню опций. Используйте клавиши со стрелками, чтобы выбрать параметр, и Enter, чтобы подтвердить и загрузить выбранную запись.

Если вы видите только обратный отсчет, но не меню, нажмите Shift, чтобы вызвать меню.

Чтобы изменить параметр, выберите его с помощью клавиш со стрелками и нажмите E. Появится окно редактора с содержимым пункта меню, связанного с этим параметром, как определено в `/boot/grub/grub.cfg`.

После редактирования параметра нажмите Ctrl+X или F10 для загрузки или Esc, чтобы вернуться в меню.

Чтобы войти в оболочку GRUB 2, нажмите C на экране меню (или Ctrl+C) в окне редактирования). Вы увидите командную строку, подобную этой: 
```
grub >
```

Введите `help`, чтобы увидеть список всех доступных команд, или нажмите Esc, чтобы выйти из оболочки и вернуться на экран меню.

Помните, что это меню не появится, если для `GRUB_TIMEOUT` установлено значение 0 в `/etc/default/grub`.

## Загрузка из оболочки GRUB 2

Вы можете использовать оболочку GRUB 2 для загрузки системы в случае, если неправильная конфигурация в пункте меню приведет к ее сбою.

Первое, что вы должны сделать, это выяснить, где находится загрузочный раздел. Вы можете сделать это с помощью команды ls, которая покажет вам список разделов и дисков, найденных GRUB 2.
```
grub> ls
(proc) (hd0) (hd0,msdos1)
```

В приведенном выше примере все просто. Есть только один диск (`hd0`) с одним разделом на нем: `(hd0,msdos1)`.

Перечисленные диски и разделы в вашей системе будут другими. В нашем примере первый раздел `hd0` называется `msdos1`, потому что диск был разбит с использованием схемы разбиения MBR. Если бы он был разделен с использованием GPT, имя было бы gpt1.

Для загрузки Linux нам понадобится ядро ​​и начальный RAM-диск (`initrd`). Проверим содержимое `(hd0,msdos1)`:
```
grub> ls (hd0,msdos1)/
lost+found/ swapfile etc/ media/ bin/ boot/ dev/ home/ lib/ lib64/ mnt/ opt/ proc/ root/ run/ sbin/ srv/ sys/ tmp/ usr/ var/ initrd.img initrd.img.old vmlinuz cdrom/
```

Вы можете добавить параметр `-l` к `ls`, чтобы получить длинный список, аналогичный тому, что вы получили бы на терминале Linux. Используйте Tab для автозаполнения имен дисков, разделов и файлов.

Обратите внимание, что у нас есть образы ядра (`vmlinuz`) и initrd (`initrd.img`) прямо в корневом каталоге. Если нет, мы можем проверить содержимое `/boot` с помощью list` (hd0,msdos1)/boot/`.

Теперь установите загрузочный раздел:
```
grub> set root=(hd0,msdos1)
```

Загрузите ядро ​​​​Linux с помощью команды linux, за которой следует путь к ядру и параметр `root=`, чтобы сообщить ядру, где находится корневая файловая система для операционной системы.
```
grub> linux /vmlinuz root=/dev/sda1
```

Загрузите исходный RAM-диск с помощью `initrd`, а затем укажите полный путь к файлу `initrd.img`:
```
grub> initrd /initrd.img
```

Теперь загрузите систему с помощью `boot`.

## Загрузка из Rescue Shell

В случае сбоя загрузки GRUB 2 может загрузить упрощенную версию спасательной оболочки.

оболочки, о которой мы упоминали ранее. Вы узнаете его по командной строке, которая отображается как спасение grub>.

Процесс загрузки системы из этой оболочки почти такой же, как показано выше. Однако вам нужно будет загрузить несколько модулей GRUB 2, чтобы все заработало.

Узнав, какой раздел является загрузочным (с помощью ls, как показано ранее), используйте команду `set prefix=`, за которой следует полный путь к каталогу, содержащему файлы GRUB 2. Обычно `/boot/grub`. В нашем примере:
```
grub rescue> set prefix=(hd0,msdos1)/boot/grub
```

Теперь загрузите модули normal и linux с помощью команды insmod:
```
grub rescue> insmod normal
grub rescue> insmod linux
```

Затем установите загрузочный раздел с помощью `set root=`, как было указано ранее, загрузите ядро ​​Linux (с помощью linux), начальный RAM-диск (`initrd`) и попробуйте загрузиться с загрузкой.