Глава 3. Начальный загрузчик GRUB
Содержание
Тот начальный загрузчик, который используют системы Linux в эти дни это GRUB версии 2. Самая первый стабильный выпуск GRUB 2 состоялся в 2012, однако он начал появляться в Linux корпоративного уровня в 2014 с Centod 7 и RHEL 7. После 2015 он наблюдался как широко адаптированный в почти всех популярных дистрибутивах Linux. Обычно, когда пользователи сообщают об ошибках или запрашивают новые функциональные возможности, разработчики прислушиваются к получаемым отзывам, расставляют приоритеты и в конечном счёте запускают некую новую версию кода. Тем не менее, в случае GRUB это работает несколько иным способом. Разработчики GRUB приняли решение изменить всю структуру GRUB 2 в то время, когда пользователи были счастливы с наследуемым GRUB (версии 1).
"Наследуемый GRUB превратился в не поддающийся поддержке из- за неряшливого кода и неудачного проектирования. Мы получили большое число запросов на новые функции и расширили GRUB за рамки первоначальной сферы, при этом не изменяли его конструкцию. Это привело к тому, что больше не возможно было расширять GRUB без переосмысления всего с самого начала."
Вот некоторые предоставляемые или находящиеся в разработке функциональные возможности GRUB:
-
Полная поддержка USB.
-
Поддержка LUKS (Linux Unified Setup Key, Унифицированного ключа установки Linux). LUKS выступает стандартом для шифрования жёсткого диска Linux.
-
Модная реализация меню, которая обладает анимацией, эффектами, таблицами стилей и т.п.
-
Инструмент "parted" будет добавлен в имеющийся начальный загрузчик. После его добавления пользователи смогут редактировать настройки диска в момент загрузки.
Данная глава рассмотрит следующее:
-
Как GRUB 2 реализуется для встроенного ПО BIOS и UEFI.
-
Относящиеся к встроенному ПО структурные изменения в GRUB 2.
-
Функциональные возможности спецификации начального загрузчика GRUB 2.
-
Функциональная возможность Безопасного запуска UEFI и то как она реализована в GRUB 2.
-
Некоторые относящиеся к начальному загрузчику проблемы и как их можно исправлять.
Как мы уже видели, GRUB получает управление от встроенного ПО. Это означает, что ему приходится иметь дело как с UEFI, так и с BIOS. Для начала давайте рассмотрим как GRUB 2 был реализован для систем на основе BIOS.
GRUB 2 в системах на основе BIOS удерживает все свои файлы в трёх различных местоположениях.
-
/boot/grub2/
-
/etc/default/grub
-
/etc/grub.d/
В случае Ubuntu версия 2 не применяется в именовании GRUB, а потому это будет /boot/grub/
вместо /boot/grub2/
, grub-install
вместо grub2-install
и grub-mkconfig
вместо grub2-mkconfig
.
Давайте обсудим эти местоположения и их содержимое.
/boot/grub2
Это то местоположение, в котором будет установлен GRUB 2. Как вы можете видеть на Рисунке 3-1, этот каталог содержит основные файлы ядра начального загрузчика.
Device.map
GRUB не понимает названия дисков такие как sda
или
vda
, так как эти соглашения об именование дисков были созданы драйверами SCSI
операционной системы. Очевидно, что GRUB исполняется когда ваша ОС ещё не представлена, а потому он обладает своим
собственным соглашением именования дисков. Ниже приводятся соглашения об именовании дисков GRUB:
Версия GRUB | Соглашение именования дисков | Значение |
---|---|---|
|
|
Жёсткий диск номер 0 и раздел номер 1, который обладает разделом таблиц MS-DOS |
|
|
Жёсткий диск номер 2 и раздел номер 3, который обладает разделом таблиц MS-DOS |
|
|
Жёсткий диск номер 3 и раздел номер 1, который обладает разделом таблиц GPT |
|
|
Жёсткий диск номер 0 и раздел номер 0 |
В GRUB номер жёсткого диска начинается с 0, а номера его разделов стартуют с 1, в то время как соглашения об
именовании дисков и разделов ОС стартуют с 1. Поскольку соглашения об именовании дисков ОС и GRUB различны, следует
устанавливать соответствие для пользователей и именно по этой причине был создан файл
device.map
.
# cat /boot/grub2/device.map
# this device map was generated by anaconda
(hd0) /dev/sda
Этот файл device.map
будет применяться
grub2-install
в качестве команд для понимания на каком из дисков установлены
файлы ядра GRUB. Вот некий образец такого файла:
# strace -o delete_it.txt grub2-install /dev/sda
Installing for i386-pc platform.
Installation finished. No error reported.
# cat delete_it.txt | grep -i 'device.map'
openat(AT_FDCWD, "/boot/grub2/device.map", O_RDONLY) = 3
read(3, "# this device map was generated "..., 4096) = 64
openat(AT_FDCWD, "/boot/grub2/device.map", O_RDONLY) = 3
read(3, "# this device map was generated "..., 4096) = 64
Наша команда grub2-install
получит ввод в виде соглашений именования дисков
ОС, так как пользователи не осведомлены о соглашениях именования дисков GRUB. В процессе своего выполнения
grub2-install
преобразует соглашения об именовании дисков SCSI в соглашения
об именовании дисков GRUB считав файл device.map
.
grub.cfg
Это основной файл настрое GRUB. Как вы можете видеть на
Рисунке 3-2,
это гигантский файл сценария, который вырабатывается по ссылкам на прочие файлы сценариев, которые мы вскоре
обсудим. Настоятельно предлагается не вносить изменения в само содержание grub.cfg
,
поскольку это может превратить вашу версию Linux в не запускаемую. Именно этот файл является тем, из которого Часть 3
GRUB получает такие инструкции как:
-
Местоположение своего ядра и initramfs
-
/boot/vmlinuz-<version>
-
/boot/initramfs-<version>
-
-
Подобные командам параметры ядра
-
Название корневой файловой системы и её местоположения и т.п.
-
Как вы можете увидеть отсюда, GRUB обладает своим собственным набором команд:
Команда GRUB | Назначение |
---|---|
|
Выводит на печать на экран имеющийся заголовок. |
|
Предоставит названия диска и раздела в которых хранятся необходимое ядро и initramfs |
|
Значение абсолютного пути к самому файлу ядра Linux |
|
Значение абсолютного пути к самому файлу initramfs Linux |
Итак, последовательность запуска GRUB 2 в системе Fedora на основе BIOS следующая:
-
Включается электропитание: вначале BIOS, далее POST, затем BIOS и после этого самый первый сектор.
-
Первой идёт самораскрутка (Часть 1 GRUB), затем Часть 2 GRUB и потом Часть 3 GRUB.
-
Часть 3 GRUB считает только что показанный
grub.cfg
из/boot/grub2/
(в случае Ubuntu это будет/boot/grub/
) и выдаст на печать приветственное окно, как это отображено на Рисунке 3-3.
-
В тот момент как пользователь выбирает
menuentry
, будут запущены командыset root
,linux
иinitrd
и стартует загрузка в оперативную память необходимых ядра и initramfs. -
В подобных Fedora дистрибутивах Linux вы обнаружите другой подход. Будет иметься файл
grub.cfg
, однако командыmenuentry
,set root
,linux
иinitrd
будут недоступны вgrub.cfg
. Тогда это некая новая разработка восходящего проекта GRUB с названием BLS. Мы обсужим её позднее в этом разделе.
i386-pc
Этот каталог имеет в себе модули (драйверы) всех имеющихся сопровождаемых GRUB файловых систем (обратитесь,
пожалуйста, к
Рисунку 3-4.
Все файлы *.mod
являются такими модулями. Применяя эти модули GRUB способен
загружать необходимые файлы ядра и initramfs в оперативную память. Например,
/boot
в этой системе обладает файловой системой
ext4
, а потому, очевидно, при выявлении и загрузке файлов
vmlinuz
и initramfs
из
/boot
, GRUB требуется модуль ext4
,
который он и получает из файла ext4.mod
. Аналогично для
/boot
в файловой системе XFS или UFS; следовательно, файлы
xfs.mod
и ufs.mod
представлены в
/boot/grub2/i386-pc
. В то же самое время вы обнаружите такие файлы как
http.mod
и pxe.mod
. Это означает, что
Часть 3 GRUB 2 может загружать необходимые файлы ядра и initramfs с устройств
http
и pxe
. В целом, файлы
*.mod
добавляют функциональные возможности, а не просто устройства. Эти
возможности будут включать в себя поддержку устройства, поддержку файловой системы или сопровождение протокола.
Ранее, /boot
под LVM был не возможен и причина этого была простой. GRUB
не понимал устройства LVM. Для распознавания и сборки необходимого устройства LVM GRUB потребуется модуль LVM, а
также такие исполняемые файлы как vgscan
, vgchange
,
pvs
, lvscan
и т.п.. Это увеличивало бы
размер GRUB как пакета; следовательно, производители основных корпоративных систем Linux всегда избегали
/boot
на устройствах LVM. Однако после введения UEFI GRUB начал поддерживать
/boot
и на устройствах LVM.
Как вы можете видеть на
Рисунке 3-5,
помимо таких файлов *.mod
, вы обнаружите и пару прочих файлов в рассматриваемом
нами местоположении /boot/grub2/i386-pc/
.
Файл core.mod
это Часть 3 GRUB 2. Поэтому последовательность запуска
Linux становится следующей:
-> Power on -> BIOS -> POST -> BIOS ->
-> Часть 1 GRUB2 -> Часть 2 GRUB2 -> core3.img -> grub.cfg ->
-> if /boot находится в файловой системе xfs -> /boot/grub2/i386-pc/xfs.mod ->
-> загружаем vmlinuz & initramfs в основную оперативную память.
После того как наше ядро в оперативной памяти, задание GRUB 2 выполнено. Об оставшейся части последовательности запуска будет заботиться само ядро, которое мы обсудим в Главе 4.
/etc/default/grub
Другой важный файл, это конечон же /etc/default/grub
. Обратите, пожалуйста,
внимание на Рисунок 3-6.
Этот файл используется GRUB для принятия косметических исправлений и изменений командной строки ядра от своего пользователя.
$ cat /etc/default/grub
GRUB_TIMEOUT=10
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="resume=/dev/mapper/root_vg-swap rd.lvm.lv=root_vg/root rd.lvm.lv=root_vg/swap console=ttyS0,115200 console=tty0"
GRUB_DISABLE_RECOVERY="true"
GRUB_ENABLE_BLSCFG=true
Как вы можете видеть, в этом файле мы можем изменять значение таймаута по умолчанию приветственного окна GRUB, значение шрифта, значений подменю и параметры командной строки ядра, такие как название его корневого устройства, название устройства подкачки и т.п..
/etc/grub.d/
Теперь мы дошли до того момента, который представляет реальный интерес относительно GRUB 2.
GRUB 2 обладает командой с названием grub2-mkconfig
. Её название
подразумевает, что она сделает необходимый файл настроек GRUB grub.cfg
,
который будет справочным для Части 3 GRUB при отображении своего приветственного окна. Файл
grub2-mkconfig
вначале получит имеющиеся входные параметры косметических
исправлений и командной строки ядра из /etc/default/grub
и запустит необходимые
файлы сценария, перечисленные на
внимание на Рисунке 3-7
из своего каталога /etc/grub.d/
.
Как вы можете видеть, эти файлы обладают назначенными им номерами вместе с собой. Это означает, что они будут запускаться по порядку.
Соответствующие файлы сценариев 00_header
,
01_users
, 08_fallback_counting
,
10_reset_boot_success
и 12_menu_auto_hide
выполнят работу по уборке. Например, файл сценария 00_header
grub.cfg
отвечает за добавление некого заголовка в собираемый файл.
Скажем для примера, чо после выполнения файла grub2-mkconfig
в Linux Fedora
к grub.cfg
будет добавлен такой заголовок:
### BEGIN /etc/grub.d/00_header ###
set pager=1
if [ -f ${config_directory}/grubenv ]; then
load_env -f ${config_directory}/grubenv
elif [ -s $prefix/grubenv ]; then
load_env
fi
if [ "${next_entry}" ] ; then
set default="${next_entry}"
set next_entry=
save_env next_entry
set boot_once=true
else
set default="${saved_entry}"
fi
if [ x"${feature_menuentry_id}" = xy ]; then
menuentry_id_option="--id"
else
menuentry_id_option=""
fi
export menuentry_id_option
if [ "${prev_saved_entry}" ]; then
set saved_entry="${prev_saved_entry}"
save_env saved_entry
set prev_saved_entry=
save_env prev_saved_entry
set boot_once=true
fi
function savedefault {
if [ -z "${boot_once}" ]; then
saved_entry="${chosen}"
save_env saved_entry
fi
}
function load_video {
if [ x$feature_all_video_module = xy ]; then
insmod all_video
else
insmod efi_gop
insmod efi_uga
insmod ieee1275_fb
insmod vbe
insmod vga
insmod video_bochs
insmod video_cirrus
fi
}
terminal_output console
if [ x$feature_timeout_style = xy ] ; then
set timeout_style=menu
set timeout=5
# Fallback normal timeout code in case the timeout_style feature is
# unavailable.
else
set timeout=5
fi
### END /etc/grub.d/00_header ###
The 08_fallback_counting script file will add the following contents in grub.cfg:
### BEGIN /etc/grub.d/08_fallback_counting ###
insmod increment
# Check if boot_counter exists and boot_success=0 to activate this behaviour.
if [ -n "${boot_counter}" -a "${boot_success}" = "0" ]; then
# if countdown has ended, choose to boot rollback deployment,
# i.e. default=1 on OSTree-based systems.
if [ "${boot_counter}" = "0" -o "${boot_counter}" = "-1" ]; then
set default=1
set boot_counter=-1
# otherwise decrement boot_counter
else
decrement boot_counter
fi
save_env boot_counter
fi
### END /etc/grub.d/08_fallback_counting ###
Как вы можете видеть, этот файл добавляет тот код, который будет отслеживать устанавливаемое по умолчанию
значение таймаута приветственного окна GRUB, точно также все остальные файлы (10_reset_boot_success
и 12_menu_auto_hide
) выполнят работу по приборке для GRUB. Давайте рассмотрим
те файлы сценариев,которые превращают GRUB 2 в один из наилучших начальных загрузчиков для множественной загрузки.
10_linux
Этот файл содержит почти 500 строк файла сценария bash. Всякий раз когда некий пользователь выполняет команду
grub2-mkconfig
, она запускает этот сценарий.
10_linux
обнаружит какие прочие дистрибутивы Linux вы установили в своей системе.
Он итеративно пройдёт раздел за разделом и отыщет все прочие версии Linux, которые были установлены в вашей системе.
Если существует какая- то ещё, она сделает в grub.cfg
некую
menuentry
. Совместно с menuentry
она добавит соответствующие записи ядра и initramfs. Ну не замечательно ди?
Положим, вы установили первой Ubuntu и следом Fedora; теперь вам не придётся добавлять записи Ubuntu вручную в
grub.cfg
Fedora. Вам всего лишь требуется запустить
grub2-mkconfig
. Эта команда исполнит для нас
10_linux
, а она в конечном счёте обнаружит что установлен Ubuntu и добавит
для неё соответствующую запись.
20_linux_xen
После 10_linux
этот файл сценария обнаружит имеет ли ваша система
установленным ядро XEN. Если это так, он добавит надлежащую запись для него в
grub.cfg
. Большинство распространителей Linux поставляют XEN как некий
отдельный пакет ядра. XEN в основном применяется гипервизорами.
20_ppc_terminfo
Если ваша система обладает архитектурой PPC или PowerPC лт IBM, тогда этот файл сценария обнаружит соответствующее
ядро и добавит необходимую надлежащую запись в grub.cfg
.
30_os_prober
Когда вы имеете на своём HDD установленными ОС не на основе Linux, тогда этот файл сценария обнаружит такую ОС
и сделает соответствующую запись для неё. Иными словами, если у вас имеется установленный в вашей системе Windows,
он автоматически обнаружит его и выполнит надлежащую запись в grub.cfg
.
Именно по этой причине после установки нашей третьей ОС (Fedora 31) в системе UEFI, мы получили полный перечень
операционных систем ничего не предпринимая. На
Рисунке 3-7
вы можете видеть представляемый Fedora 31 приветственный экран.
После установки Fedora, Anaconda запускает grub2-mkconfig
в фоновом
режиме, который в конечном счёте запустил 30_os_prober
и он отыскивает нашу
установку и сделает соответствующую запись для него в grub.cfg
.
30_uefi-firmware
Этот сценарий успешно запустится только когда вы обладаете системой UEFI. Основная задание этого файла сценария
состоит в добавлении всех соответствующих записей встроенного ПО UEFI в grub.cfg
.
Как вы можете увидеть на
Рисунке 3-8,
файлом сценария 30_uefi-firmware
была добавлена запись
System setup
.
### BEGIN /etc/grub.d/30_uefi-firmware ###
menuentry 'System setup' $menuentry_id_option 'uefi-firmware' {
fwsetup
}
### END /etc/grub.d/30_uefi-firmware ###
Если наш пользователь выбирает предоставленный вариант "System setup", тогда он запустит обратно это встроенное ПО UEFI. На Рисунке 3-9 вы можете видеть интерфейс встроенного ПО UEFI.
40_custom и 41_custom
Эти записи предоставляются своему пользователю в случае когда этот пользователь желает добавить некие
индивидуальные записи в grub.cfg
. Например, когда
grub2-mkconfig
отказывает в добавлении любой из установленных ОС в
качестве записей, тогда пользователь добавить некую индивидуальную запись в эти два индивидуальных файла. Вы
можете делать свои собственные индивидуальные файлы, но вам следует убедиться что каждый обладает неким назначенным
ему номером и обладает полномочиями на выполнение.
И снова имеются три местоположения в которых GRUB 2 хранит свои файлы. Рисунок 3-10 отображает соответствующие каталоги и их файлы.
Файл grub.cfg
, который был показан ранее в
/boot/grub2/
, был передвинут в ESP
(/boot/efi/EFI/fedora/
). Кроме того, как вы можете видеть, не существует
каталога i386-pc
. Это из- за того, что EFI предоставляет богатую поддержку
устройств и файловых систем. Внутри ESP вы можете обнаружить пару файлов *.efi
,
в том числе исполняемые файлы shim.efi
и
grubx64.efi
. Файл etc/default/grub
,
который отвечает за косметические изменения и для параметров командной строки ядра всё ещё пребывает в том же самом
местоположении. Файл device.map
не доступен, так как команда
grub2-install
не имеет значения в системах UEFI. Позднее в этой главе мы обсудим
эту команду.
BLS (Boot Loader Specification, Спецификация начального загрузчика) это новая разработка в восходящем проекте GRUB которая пока не была адаптирована для многих дистрибутивов основного потока. В частности, эта схема была адаптирована операционными системами на основании Fedora, таких как RHEL, Fedora, Centos, Oracle Linux, и т.п., но не дистрибутивами на основе Debian, таких как Ubuntu, Mint и т.п..
В системах на основе BIOS, в которых ОС обладающая контролем над самыми первыми 512 байтами обладает контролем
над последовательностями запуска всех имеющихся операционных систем, именно по этой причине всякая ОС пытается
получить удержание этих самых первых 512 байт. Такая ситуация возникает потому, что наш BIOS всегда запускается в
самых первых 512 байтах своего HDD и вызывает Часть 1 своего начального загрузчика (самораскрутку). Переход этой
Части 1 к Части 2 и от Части 2 к Части 3 происходит позднее и затем в самом конце Часть 3 считывает особый для
своего начального загрузчика файл настроек (bcdedit
в случае Windows,
grub.cfg
при варианте с Linux). Еси такой файл настроек обладает соответствующими
записями для прочих установленных ОС, тогда они получат шанс для запуска. Итак, длинная история вкратце:
всякий кто обладает контролем над самыми первыми 512 байтами контролирует всю последовательность запуска. Однако в
случае с ESP все ОС получают некую равную возможность запуска, так как UEFI проверяет имеющиеся каталоги ESP и
перечисляет записи всех доступных ОС. Разработчики стали задаваться вопросом могут ли они получить нечто подобное
в системе на основе BIOS и они придумали BLS.
В BLS было введено некое новое местоположение (пятое) для хранения необходимых файлов относящихся к начальному
загрузчику, и это /boot/loader/
. Итак, у нас теперь имеется пять
расположений в которых GRUB будет хранить свои файлы.
-
/boot/grub2/
-
/etc/default/grub
-
/etc/grub.d/
-
boot/efi/EFI/<OS_vendor>/
(только в случае UEFI) -
/boot/loader/ (здесь будут храниться файлы BLS)
Основная идея состоит в том, что после установки соответствующего нового ядра, это ядро само по себе со
своими сценарии по окончанию (post-scripts, нечто подобное пакету kernel-core
в случае Fedora) создаст некую запись для какого- то нового ядра в своём каталоге
/boot/loader/
. К примеру, мы установили такой пакет ядра:
# rpm -q kernel
Kernel-5.3.7-301.fc31.x86_64
Это тот же самый пакет, который предоставит соответствующие файлы /boot/vmlinuz
и /boot/initramfs
. После установки этого ядра будет подготовлен такой файл:
# cat /boot/loader/entries/36543031048348f9965e3e12e48bd2b1-5.3.7-301.fc31.x86_64.conf
title Fedora (5.3.7-301.fc31.x86_64) 31 (Thirty One)
version 5.3.7-301.fc31.x86_64
linux /vmlinuz-5.3.7-301.fc31.x86_64
initrd /initramfs-5.3.7-301.fc31.x86_64.img
options $kernelopts
grub_users $grub_users
grub_arg --unrestricted
grub_class kernel
Как вы можете видеть, этот файл обладает четырьмя записями.
-
Соответствующий заголовок, который будет выведен на печать Частью 3 GRUB
-
Значениями местоположения и названия файла своего файла ядра
-
Значениями местоположения и названия файла своего файла initramfs
-
Соответствующей переменной
$kernelopts
, которая была объявлена в файле/boot/grub2/grubenv
# cat /boot/grub2/grubenv # GRUB Environment Block saved_entry=2058a9f13f9e489dba29c477a8ae2493-5.3.7-301.fc31.x86_64 menu_auto_hide=1 boot_success=0 kernelopts=root=/dev/mapper/fedora_localhost--live-root ro resume=/dev/mapper/fedora_localhost--live-swap rd.lvm.lv=fedora_localhost-live/root rd.lvm.lv=fedora_localhost-live/swap rhgb quiet boot_indeterminate=0
В целом, $kernelopts
предоставляет параметры командной строки ядра, такие
как название своей корневой файловой системы (/dev/mapper/fedora_localhost--live-root
)
и в каком режиме её надлежит монтировать (ro - read only
, только для чтения).
Итак, имеющаяся последовательность запуска становится подобна такой:
-
BIOS -> POST -> BIOS
-
Часть 1 GRUB -> Часть 2 GRUB -> Часть 3 GRUB
-
Часть 3 GRUB -> считывает
grub.cfg
-
Часть 3 GRUB -> считывает
/boot/loader/entries/*
-
Выводит на печать все заголовки файлов, представленных в
/boot/loader/entries
В качестве некого примера, рассмотрим некую установленной новую ОС или некое новое ядро. Это должно выработать
свой собственный файл записи и поместить его в каталог /boot/loader/entries/
самого первого раздела. Таким образом, всякий раз когда Часть 3 GRUB ОС из самого первого первичного раздела считывает
установленные записи, все прочие ОС будут иметь возможность для запуска. Такой файл записи может быть создан
при помощи команды Fedora kernel-install
.
#kernel-install add 5.3.7-301.fc31.x86_64 /lib/modules/5.3.7-301.fc31.x86_64/vmlinuz
Данная команда создаст надлежащую запись для kernel-5.3.7-301.fc31.x86_64
в /boot/loader/entries/
, как это показано здесь:
# ls /boot/loader/entries/ -l
total 8
-rw-r--r--. 1 root root 329 Dec 9 10:18 2058a9f13f9e489dba29c477a8ae2493-0-rescue.conf
-rw-r--r--. 1 root root 249 Oct 22 01:04 2058a9f13f9e489dba29c477a8ae2493-5.3.7-301.fc31.x86_64.conf
Значение числа, связанного с файлом *.conf
уникально. Такая BLS обладает
своими преимуществами и недостатками.
Вот преимущества:
-
Всякая ОС получает равные возможности для запуска.
-
Это срабатывает вне зависимости от наличия встроенным ПО BIOS или UEFI.
-
В случае системы с BIOS, самая последняя установка Linux удалит Части 1 и 2 ранее установленных операционных систем, которые устарели с момента последней установки Linux, сделав свою собственную запись посредством команды
kernel-install
в более ранних ОС.
А вот недостатки:
-
BLS пока ещё не полностью реализована. Когда имеющаяся вторая ОС желает сделать свою запись в своей первой ОС, тогда
/boot
этой первой ОС должен иметь разделяемый доступ. Это не является тем вариантом, который представлен сейчас. Поэтому я рассматриваю это как некую половину реализации. -
BLS усложняет без необходимости имеющуюся последовательность запуска, так как нам приходится обладать двумя файлами настройки для справок:
grub.conf
и<uniq_no><kernel_version>.conf
из/boot/loader/entries/
. BLS особенно усложняет жизнь в случае разрешения проблем "can’t boot". -
За исключением дистрибутивов на основе Fedora ни один прочий пока ещй не адаптировал BLS, что выглядит как имеющее предпосылки стать обшим решением. Походе, что именно Fedora является наиболее заинтересованным в разработке этого проекта; следовательно, BLS была реализована в Fedora.
На основании этих знаний давайте попытаемся разрешить некоторые из наиболее распространённых проблем "невозможности запуска", связанных с начальным загрузчиком.
Проблема: после включения вашей системы она проваливается в приглашение на ввод GRUB, как это показано на Рисунке 3-11:
Это именно то, что вы наблюдаете на своём экране. Вы должны были сталкиваться с этой ошибкой хотя бы раз в своей жизни. Давайте попробуем разрешить её.
-
Вы будете способны разрешить свою проблему только если вы знаете чем вызвана данная проблема. Прямо сейчас, однако, у нас нет никаких мыслей что это за чертовщина, так как мы только запустили свою систему и получили вот это.
-
Наш экран имеет приглашение на ввод GRUB. Когда вы получили такое приглашение, это означает, что вы имеете возможность выполнять в нём команды. Помните, что это приглашение на ввод команд GRUB, что означает что вы можете получать доступ только к командам GRUB.
-
Знакомясь с Рисунком 3-11, какая менно из трёх Частей GRUB какая именно из них предоставила нам это приглашение на ввод GRUB?
-
Естественно, это должна быть Часть 3, потому как Часть 1 и Часть 2 слишком малы в размере, а потому они не могут обладать такой функциональностью. Итак, мы успешно достигли Части 3 GRUB и, что наиболее важно, не имеет значения будет ли эта система обладать UEFI или BIOS. Поскольку мы достигли Части 3, это означает, что мы покинули среду своего встроенного ПО. Это критически важные исходные сведения. Теперь мы можем сосредоточиться только на Части 3.
-
В чём состоит основная цель Части 3 GRUB? Она считывает
grub.cfg
и из него получает местоположения своих ядра и initramfs. Если это система с включённой BLS, тогда она получает названия ядра и initramfs из каталогов/boot/loader/entries/
. Например, допустим, наша система не осведомлена о BLS. Часть 3 тогда загружаетvmlinuz
и initramfs в оперативную память. -
Поскольку Часть 3 предоставила нам приглашение на ввод GRUB, но отказала в загрузке самой ОС, это означает, что либо файлы ядра или initramfs не представлены, либо наш файл
grub.cfg
не указывает правильно на местоположение этих файлов. -
Итак, в подобном случае мы можем попытаться запустить Fedora вручную. Вручную означает, что мы предоставим файлы ядра и initramfs с абсолютными путями при помощи приглашения на ввод GRUB. Вот как мы это делаем.
-
linux
это команда GRUB через которую нам требуется предоставить абсолютный путь к своему файлу ядра (vmlinuz
). Как мы знаем, файлvmlinuz
находится в/boot
и GRUB следует своему собственному соглашению об именовании дисков. Таким образом, нашим путём к/boot
будет жёсткий диск с номером 0 и раздел номер 1. Конечно, вы можете быть не осведомлены на каком HDD или в каком разделе хранится/boot
. В этом случае вы можете получить справку у функциональности автозавершения GRUB. Вы можете нажать Tab дважды и GRUB выведет для вас доступные возможности. Давайте найдём номера HDD и раздела/boot
. Обратите внимание на Рисунок 3-12.
Самая первая табуляция после
hd0
покажет нам что существует два раздела доступных в жёстком диске с номером0
. Второй раздел не читается из GRUB, а потому, естественно, второй раздел не способен быть/boot
. Следовательно, мы выбираем разделmsdos1
. Затем, как это отображено на Рисунке 3-13, мы начнём поиск необходимого файлаvmlinuz
там при помощи автозаполнения.
Как вы можете видеть внутри HDD номер 0 и раздела номер 1 мы обнаружили два файла
vmlinuz
; один является аварийным ядром, а другой это обычный файл ядра Fedora 31. Как показано на Рисунке 3-14, мы выберем это обычное ядро и предоставим ему название его корневой файловой системы, затем вы сможете запустить эту систему с аварийным или live образом и проверить значение записей/etc/fstab
. Мы обсудим аварийный режим в Главе 10.
Значением абсолютного пути к файлу
vmlinuz
является(hd0,msdos1)/vmlinuz-5.3.7-301.fc31.x86_64
. Вслед за ним следует параметр командной строкиro
является , что является сокращением "read-only". Послеro
у нас имеется передаваемое нашей системой название файловой системыroot
, которым выступает/dev/mapper/fedora_localhost--live-root
.grub> linux (hd0,msdos1)/vmlinuz-5.3.7-301.fc31.x86_64 ro root=/dev/mapper/fedora_localhost--live-root
После успешного выполнения команды
linux
нам требуется передать название своей initramfs. Доступными для выполнения этого у нас имеются две команды:initrd
иinitrd16
. Обратите внимание, пожалуйста на Рисунок 3-15.grub> initrd (hd0,msdos1)/initramfs-5.3.7-301.fc31.x86_64.img
-
В тот момент как вы исполните свою команду
boot
, как это отражено на Рисунке 3-16 и Рисунке 3-17, Часть 3 GRUB получит эти входные данные и загрузит/boot/vmlinuz-5.3.7-301.fc31.x86_64 (hd0,msdos1)
. Затем она загрузит/boot/initramfs-5.3.7-301.fc31.x86_64.img
и передаст управление этому ядру. Данное ядро в конечном счёте смонтирует корень (/
) файловой системы из/dev/mapper/fedora_locahost--live-root
в свой каталог/
и отобразит экран входа в систему.
-
В случае Ubuntu 18 эти команды слегка иные. В Fedora 31 мы выдавали адрес своего раздела
/boot
напрямую самой командеlinux
, в то время как в Ubuntu нам придётся иметь для этого отдельную команду GRUB с названиемset root
.Как вы можете видеть на Рисунке 3-18, устанавливаемым названием корневой файловой системы в системе Ubuntu 18 является
/dev/sda1
. Это стандартный раздел, в отличии от устройстваlvm
Fedora 31.
-
Как только мы предоставим надлежащие входные сведения GRUB 2, он приведёт нас к экрану входа в систему. Вы можете наблюдать этот экран входа в систему на Рисунке 3-19.
-
Возвращаясь обратно к нашей системе Fedora, поскольку сейчас она была загружена, мы имеем возможность восстановить свой файл
grub.cfg
воспользовавшись командойgrub2-mkconfig
, как это отображено на Рисунке 3-20.
В случае с Ubuntu мы можем выполнить
grub-mkconfig
. Взгляните на Рисунок 3-21.
Однако если бы это была бы система UEFI, а вы бы желали восстановить
grub.cfg
, тогда, как это продемонстрировано на Рисунке 3-22, местоположениемgrub.cfg
был бы ESP.
-
После того как
grub.cfg
создан, нам требуется восстановить для Fedora соответствующие записи BLS.#kernel-install add 5.3.7-301.fc31.x86_64 /lib/modules/5.3.7-301.fc31.x86_64/vmlinuz
Данная команда сделает соответствующую запись для ядра
kernel-5.3.7-301.fc31.x86_64
в/boot/loader/entries/
.# ls /boot/loader/entries/ -l total 8 -rw-r--r--. 1 root root 329 Dec 9 10:18 2058a9f13f9e489dba29c477a8ae2493-0-rescue.conf -rw-r--r--. 1 root root 249 Oct 22 01:04 2058a9f13f9e489dba29c477a8ae2493-5.3.7-301.fc31.x86_64.conf
-
Когда Fedora располагается в системе UEFI , тогда шаг BLS останется тем же самым.
-
После перезагрузки Fedora способная гладко выполнить запуск и проблема "can’t boot" окажется исправленной.
Проблема: После включения системы она проходит стадию встроенного ПО, однако после этого, как вы можете это видеть на Рисунке 3-23, на вашем экране ничего нет.
Решение для систем на основе BIOS
Вот шаги по решению этого:
-
Так как стадия встроенного ПО BIOS была пройдена, это означает, что что- то пошло не так на уровне имеющегося начального загрузчика.
-
Поскольку мы не получили ничего на своём экране, это означает, что Часть 1 или Часть 2 GRUB отсутствует, либо, в крайнем случае повреждена (512 байт + 31 кБ). Если бы была достигнута Часть 3, тогда мы по крайней мере получили бы приглашение на ввод GRUB. Итак, проблема была выделена и наш план действий состоит в замене Части 1 и Части 2 GRUB.
-
Это можно осуществить при помощи команды
grub2-install
. Прежде всего загрузитесь с носителя live того же самого дистрибутива Linux или, когда это доступно, загрузитесь в аварийном режиме. Пояснения по самим образу live и аварийному режиму мы дадим в Главе 10.
Как вы можете видеть на
Рисунке 3-24,
grub2-install
получает на входе значение названия устройства. Обратите,
пожалуйста, внимание что это название устройства не должно быть номером раздела; вместо этого оно должно представлять
название диска. Это обусловлено тем, что Часть 1 и Часть 2 GRUB должны быть установлены в самых первых 512 байтах +
31 кБ диска, а не внутри раздела. Вам необходимо заменить sda
на название
вашего диска.
Помимо файлов Части 1 и Части 2 своего начального загрузчика, grub2-install
восстановит или повторно установит свой каталог i386-pc
, который обладает
всеми модулями своего начального загрузчика GRUB 2. Мы можем перекрёстно проверить это, установив эти модули в
некий индивидуальный каталог. Обратитесь, пожалуйста к
Рисунку 3-25.
Вы можете видеть, что все файлы GRUB 2 были восстановлены совместно с файлами модулей GRUB.
# ls temp/grub2/
fonts grubenv i386-pc
# ls -l temp/grub2/i386-pc/ | wc -l
279
После перезагрузки Fedora должен запуститься нормально и проблема "can’t boot" должна быть
исправленной. Если GRUB выбросит вам своё приглашение на вод команд, тогда вам потребуется пройтись шагами,
упомянутыми в Проблема 1 "Can’t Boot" (начальный
загрузчик), поскольку grub2-install
восстановил необходимые
исполняемые файлы, однако не выработал повторно файл grub.cfg
.
Но что если мы сталкиваемся с этой проблемой в системе на основе UEFI?
Решение для систем на основе UEFI
Вот наши шаги:
-
Как вы уже могли догадаться, нам всего лишь придётся изменить название передаваемого для нашей команды
grub2-install
устройство, как это и показано на Рисунке 3-26. Названием этого устройства должен быть ESP.
Проблема: Полное отсутствие
/boot
.
Решение для систем на основе BIOS
Вот наши шаги:
-
Восстановление утраченного
/boot
(или же, по крайней мере, оно выходит за рамки данной книги). -
Загрузитесь в аварийном режиме или с носителя live и смонтируйте файловую систему корня нашей "can’t boot" системы. Пояснения по тому как работает аварийный режим мы дадим в Главе 10.
-
Прежде всего создадим новый каталог
/boot
и установим для него надлежащие права доступа.-
#mkdir /boot
-
#chmod 555 /boot
-
#chown root:root /boot
-
Если предполагается, что
/boot
является обособленным разделом, тогда смонтируйте его в верном разделе.
-
-
Как мы знаем, именно в
/boot
хранятся необходимые файлы нашего начального загрузчика, ядра и initramfs. Поскольку/boot
утрачен, нам потребуется создать все эти файлы для него.-
#dnf reinstall kernel
-
Это верно для системы на основе Fedora. Когда это будет система на основе Debian, тогда вы можете воспользоваться командой
apt-get
и сможете переустановить своё ядро. -
Это установит необходимый файл
vmlinuz
и также повторно сгенерирует для него файл initramfs.
-
-
-
Теперь нам требуется установить GRUB.
-
#grub2-install /dev/<disk_name>
-
В нашем случае это команда
#grub2-install /dev/sda
.
-
-
Это восстановит Часть 1, Часть 2 GRUB, а также его каталог
i386-pc
из каталога/boot/grub2
. -
Для восстановления Части 3 GRUB и для получения некоторых предоставляемых GRUB инструментов нам потребуется в системе на основе Fedora установить два пакета.
-
#dnf reinstall grub2 grub2-tools
-
Как и предполагают их названия,
grub2
предоставит Часть 3 GRUB, аgrub2-tools
снабдит нас некоторыми инструментами, такими какgrub2-install
.
-
-
Теперь настало время повторно выработать файл настроек GRUB.
-
#grub2-mkconfig -o /boot/grub2/grub.cfg
-
-
Наконец, исправляем свою BLS.
-
#kernel-install add 5.3.7-301.fc31.x86_64 /lib/modules/5.3.7-301.fc31.x86_64/vmlinuz
-
-
Решение для систем на основе UEFI
Наши шаги следующие:
-
/boot/
и/boot/efi/
это отдельные точки монтирования.-
# mkdir /boot
-
# chmod 555 /boot
-
# chown root:root /boot
-
# yum reinstall kernel
-
-
Теперь нам требуется создать некий раздел ESP и, как нам известно, он обязан быть разделом VFAT. Затем мы назначим ему тип раздела ESP.
-
#mkdir /boot/efi
-
#mount /dev/sda2 /boot/efi
-
В нашем случае, тот раздел, который я создал под ESP, это
sda2
.
-
-
#grub2-install --efi-directory=/boot/efi
-
Это установит в ESP файл
grubx64.efi
.
-
-
Остальные необходимые нам файлы предоставляются пакетами
grub2-efi
,shim
иgrub2-tools
.-
#yum reinstall grub2-efi shim grub2-tools
-
-
Создадим повторно файлы настроек.
-
#grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg
-
#kernel-install add 5.3.7-301.fc31.x86_64 /lib/modules/5.3.7-301.fc31.x86_64/vmlinuz
-
-
После перезапуска нашей системы, она способно запускаться без каких бы то ни было проблем.
Теперь настало время пролить побольше света на среду Безопасного запуска UEFI.
Безопасный запуск (Secure Boot) это великолепная функциональная возможность UEFI. Он гарантирует что никакой не обладающий доверием исполняемый файл не будет выполнен при запуска До сих пор мы наблюдали следующее:
-
Цифровая подпись это некая уникальная строка.
-
Цифровая подпись всякого файла будет вырабатываться из некого частного (private) ключа.
-
Та же самая цифровая подпись может быть восстановлена по общедоступному (public) ключу.
-
В случае отсутствия изменений в этом файле эти цифровые подписи обязаны совпадать.
-
-
Microsoft изготовил свою собственную пару ключей (частный и общедоступный ключи).
-
Microsoft цифровым образом подписывает относящиеся к своему начальному загрузчику (
BCD
) файлы при помощи собственного частного ключа. -
Общедоступный ключ Microsoft представлен внутри UEFI.
-
При запуске UEFI восстанавливает значение цифровой подписи соответствующего начального загрузчика при помощи имеющегося у него общедоступного ключа {Microsoft}. Если значение цифровой подписи не совпадает, тогда UEFI отклоняет выполнение файлов
.efi
. -
Для применения этой функциональности в соответствующей средеLinux был создан некий новый начальный загрузчик с названием
shim
(Прокладка) и он был подписан частным ключом Microsoft с тем, чтобы UEFI допускал выполнениеshim.efi
. -
Задание
shim.efi
состоит в вызове реального файла GRUB, которым выступаетgrubx64.efi
.
Однако Безопасный запуск не завершается на этом. Поскольку имеется вероятность, что
grubx64.efi
может быть скомпрометирован сам по себе, или при том факте что
может оказаться скомпрометированным всякий запускаемый после соответствующего начального загрузчика код,
недостаточно безопасности имеющейся среды запуска лишь на уровне начального запуска; следовательно, в наши дни
функциональность Безопасного запуска делает безопасной всю процедуру запуска Linux. Вот как это работает:
-
Fedora подготовит свою собственную пару ключей и подпишет свои файлы GRUB частным ключом Fedora.
-
Необходимый общедоступный ключ Fedora будет оставаться внутри основного файла
shim.efi
. -
По мере продолжения этой последовательности запуска цифровая подпись GRUB будет восстанавливаться с применением необходимого общедоступного ключа, находящегося внутри
shim.efi
. -
При соответствии подписи
grubx64.efi
и прочие файлы начального загрузчика будут разрешены к исполнению из UEFI. -
Окончательное задание GRUB состоит в загрузке необходимого ядра (
/boot/vmlinuz
). -
Этот файл
vmlinuz
также может оказаться скомпрометированным, поэтому, во избежание данной ситуации, само ядро также будет подписано тем же самым частным ключом, который применялся для подписи GRUB. -
Цифровая подпись
vmlinuz
будет восстановлена при помощи находящегося внутриshim.efi
соответствующего общедоступного ключа. -
Когда полученная цифровая подпись удовлетворяет соответствию, подписанное ядро получает контроль над последовательностью запуска.
-
Однако это ядро пользуется большим числом модулей/ драйверов, который в конечном счёте вставляются вовнутрь самого ядра. Поэтому такие модули являются теми исполняемыми файлами, который снова могут оказаться скомпрометированными, а следовательно, так как они превратятся в часть ядра/
vmlinuz
, в конце концов и само по себе ядро будет скомпрометировано. -
Итак, наше ядро в качестве пакета, будет подготовлено собственной парой ключей. Все имеющиеся модули будут подписаны этой парой частных ключей ядра, а соответствующим общедоступным ключом будет снабжён сам пакет этого ядра. Значение частного ключа пакета ядра позднее будет разрушено.
-
На момент запуска при вставке соответствующих модулей в имеющееся ядро значение цифровой подписи этого модуля будет восстановлено с применением надлежащего общедоступного ключа, которое пребывает в самом ядре.
-
Следуя перечисленным шагам функциональность Безопасного запуска гарантирует выполнение лишь исполняемых модулей от доверенных сторон.
Показанная на Рисунке 3-27 блок- схема ещё больше упростит эту процедуру запуска.
Один из моих студентов задал мне вопрос: сколько операционных систем мы способны установить в одной системе и множественно загружать их из одного начального загрузчика? Я не знаю точного ответа, но я попытался найти его. Я решил, что я воспользуюсь для запуска всех устанавливаемых мною операционных систем начальным загрузчиком GRUB 2. Я устанавливал и множественно запускал эти операционные системы почти два года до настоящего момента. Я установил до сих пор 106 операционных систем. И это наша третья система, которую я назвал Jarvis. Вот аппаратные и программные подробности Jarvis:
-
Встроенное ПО UEFI.
-
Подключены два диска (
sda
иsdb
). -
Методом запуска выступает UEFI.
-
sda
отформатирован с таблицей разделов MS-DOS. -
sdb
отформатирован с таблицей разделов GPT. -
Все имеющиеся операционные системы идентифицируются и запускаются начальным загрузчиком GRUB 2.
Все установленные на моём диске sda
операционные системы устанавливались
настройкой метода запуска в UEFI и им обладают все новые операционные системы. Те операционные системы, которые
находятся на sdb
были установлены при настройке метода запуска встроенного ПО
в совместимый режим (legacy). sdb
размещает операционные системы старого поколения,
или, по крайней мере, те операционные системы, которые на обладают поддержкой UEFI. Вот подробности:
Раздел | Операционная система | Файловая система | Размер |
---|---|---|---|
|
ESP (EFI System partition) |
|
20 ГБ |
|
MSR (Microsoft recovery) |
|
16 МБ |
|
Windows 10 |
|
9.7 ГБ |
|
Swap |
|
2.01 ГБ |
|
openSUSE Linux 13.2 |
|
10 ГБ |
|
Mint Linux 17.2 |
|
10 ГБ |
|
Oracle OpenSolaris 11.2 |
|
10 ГБ |
|
Sabayon Linux 15.06 |
|
10 ГБ |
|
немного случайного свободного пространства |
|
8.4 ГБ |
|
Kali Linux 2.0 |
|
10 ГБ |
|
Arch Linux 2015-8.1 |
|
10 ГБ |
|
Debian Linux 8.1 |
|
10 ГБ |
|
Semplice Linux 7.0.1 |
|
10 ГБ |
|
Slackware 14.1 Linux |
|
10 ГБ |
|
Openmandriva 2014.2 |
|
10 ГБ |
|
Mate Ubuntu Linux15.04 |
|
10 ГБ |
|
Steam OS beta |
|
10 ГБ |
|
Manjaro Linux 0.8.13.1 |
|
10 ГБ |
|
Netrunner Linux 16 |
|
10 ГБ |
|
Windows 8 |
|
10 ГБ |
|
Korora Linux 22 |
|
10 ГБ |
|
KaoS Linux 2015.08 |
|
10 ГБ |
|
Lubuntu Linux 15.04 |
|
10 ГБ |
|
Sonar Linux 2015.2 |
|
10 ГБ |
|
Antergos Linux 2015.08.18 |
|
10 ГБ |
|
Mythbuntu Linux 14.04.2 |
|
10 ГБ |
|
Rosa Linux fresh r5 |
|
10 ГБ |
|
SparkyLinux 4.0 |
|
10 ГБ |
|
Vinux Linux 4.0 |
|
10 ГБ |
|
Xubuntu Linux 14.04.3 |
|
10 ГБ |
|
Ubuntu Studio 14.04.3 |
|
10 ГБ |
|
Suse Enterprise 12 |
|
10 ГБ |
|
Ubuntu Linux 14.04 |
|
10 ГБ |
|
Uubuntu Linux 15.04 |
|
10 ГБ |
|
Scientific Linux 7 |
|
10 ГБ |
|
Xubuntu Linux 14.04.3 |
|
10 ГБ |
|
CentoS Linux 7 |
|
10 ГБ |
|
Ubuntu Server 14 Linux |
|
10 ГБ |
|
Fedora 21 Linux |
|
10 ГБ |
|
Fedora 22 Linux |
|
10 ГБ |
|
BlackArch 2015.07.31 |
|
10 ГБ |
|
Gentoo Linux multilib 20140826 |
|
10 ГБ |
|
Calculate Linux 14.16.2 |
|
10 ГБ |
|
Fedora 20 Linux |
|
10 ГБ |
|
Fedora 23 Linux |
|
10 ГБ |
|
Manjaro Linux 15-0.9 |
|
10 ГБ |
|
Ubuntu Linux 16.04 |
|
10 ГБ |
|
chapeau Linux 23 |
|
10 ГБ |
|
Arquetype Linux 22 |
|
10 ГБ |
|
Fx64 Linux 22 |
|
10 ГБ |
|
Viperr Linux 7 |
|
10 ГБ |
|
Hanthana Linux 21 |
|
10 ГБ |
|
Qubes r3.1 Linux |
|
10 ГБ |
|
Fedora 24 |
|
10 ГБ |
|
Fedora 23 |
|
10 ГБ |
|
sabayon-16 |
|
10 ГБ |
|
Korora-24 |
|
10 ГБ |
|
Sonar 16 Linux |
|
10 ГБ |
|
Viper 9 Linux |
|
10 ГБ |
|
Arquetype Linux 23 |
|
10 ГБ |
|
Manjaro Linux 16 |
|
10 ГБ |
|
Manjaro Linux Gaming 16 |
|
10 ГБ |
|
Calculate Linux 15 |
|
10 ГБ |
Итак, общее число установок ОС UEFI на диске sda
составило 59, так как четыре
раздела были зарезервированы под обслуживание ESP- и MSR- подобных разделов. Далее следуют подробности установок
диска sdb
:
Раздел | Операционная система | Файловая система | Размер |
---|---|---|---|
|
PCBSD 10.1.2 |
|
10 ГБ |
|
Magia 2 Linux |
|
10 МБ |
|
Magia 3 Linux |
|
10 ГБ |
|
Extended/secondary |
|
примерно 970 ГБ |
|
Q4OS Linux 1.2.8 |
|
10 ГБ |
|
Qubes R2 Linux |
|
10 ГБ |
|
Pardus Linux 2013 |
|
10 ГБ |
|
GoboLinux 015 |
|
10 ГБ |
|
Crux Linux 3.1 |
|
10 ГБ |
|
Point Linux 3.0 |
|
10 ГБ |
|
Extix Linux 15.3 |
|
10 ГБ |
|
Bodhi Linux 3.0 |
|
10 ГБ |
|
Debian Linux 7.0 |
|
10 ГБ |
|
Debian Linux 6.0 |
|
10 ГБ |
|
BOSS Linux 6.1 |
|
10 ГБ |
|
CrunchBang rc1 Linux |
|
10 ГБ |
|
Handy Linux 2.1 |
|
10 ГБ |
|
Lite Linux 2.4 |
|
10 ГБ |
|
WattOS Linux r9 |
|
10 ГБ |
|
PinGuy OS 14.04.3 Linux |
|
10 ГБ |
|
SuperX 3.0 Linux |
|
10 ГБ |
|
JuLinux 10X Rev 3.1 Linux |
|
10 ГБ |
|
Black Lab Linux 2015.7 |
|
10 ГБ |
|
Hamara Linux 1.0.3 |
|
10 ГБ |
|
Peppermint LInux 20150518 |
|
10 ГБ |
|
Ubuntu 13.10 Linux |
|
10 ГБ |
|
LinuxMint 13 mate |
|
10 ГБ |
|
LinuxMint 14.1 cinnamon |
|
10 ГБ |
|
LinuxMint 15 xfce |
|
10 ГБ |
|
LinuxMint 16 Kde |
|
10 ГБ |
|
Peppermint 4 20131113 |
|
10 ГБ |
|
Peppermint 5 20140623 |
|
10 ГБ |
|
Fedora 12 |
|
10 ГБ |
|
Trisquel 7 Linux |
|
10 ГБ |
|
Oracle Linux 7.1 |
|
10 ГБ |
|
Fedora 14 Linux |
|
10 ГБ |
|
Fedora 15 Linux |
|
10 ГБ |
|
Fedora 17 Linux |
|
10 ГБ |
|
Fedora 19 Linux |
|
10 ГБ |
|
RHEL 6.5 Linux |
|
10 ГБ |
|
SolydX 201506 |
|
10 ГБ |
|
Oracle Linux 6.7 |
|
10 ГБ |
|
OpenSuse 11.3 |
|
10 ГБ |
|
LMDE (Linux Mint 2 Debian edition) |
|
10 ГБ |
|
Centrych Linux 12.04 |
|
10 ГБ |
|
Elementary OS 2013 |
|
10 ГБ |
|
Elementary OS 2015 |
|
10 ГБ |
|
Sabayon 13.08 Linux |
|
10 ГБ |
|
Deepin 2013 Linux |
|
10 ГБ |
|
Deepin 15.1 Linux |
|
10 ГБ |
Общее число запускаемых способом BIOS операционных систем на диске sdb
равно 50 -2 = 48.
Два раздела зарезервированы под подкачку и соответствующий расширенный раздел.
Итак, общее число установок в системе Jarvis составляет 106 и, как вы можете видеть на
Рисунке 3-28,
все эти ОС допускают множественную загрузку при помощи установленного начального загрузчика GRUB 2. С этим проектом
я осознал, что этому нет конца. Сочетание GRUB 2 и UEFI способны обрабатывать число
n
операционных систем.
Как я управлял установкой такого большого числа операционных систем? Элементарно. После установки каждой новой
операционной системы я запускал команду grub-mkconfig
, которая обнаруживала
все имеющиеся операционные системы на всех подключённых дисках.
# time grub-mkconfig -o multiboot_grub.cfg
Приведённая выше команда применялась после установки Ubuntu 18, которая оказалась 106 ОС в этом списке.
Как вы можете видеть на
Рисунке 3-29,
после установки 106-й ОС grub-mkconfig
потребовался почти час на завершение
и полученный в результате файл настроек GRUB обладал 5 500 строк.
Мы знаем что наш BIOS выполняет безусловный переход в самые первые 512 байт и вызывает начальный загрузчик
GRUB 2. Чтобы разобраться как именно BIOS вызывает наш начальный загрузчик мы сделаем свой собственный
начальный загрузчик. Наш начальный загрузчик будет совсем крошечным по сравнению с GRUB 2. Наш начальный загрузчик
будет всего лишь !
н нашем экране. Однако при помощи этого примера мы сможем
понять как наш BIOS выполняет безусловный переход к таким начальным загрузчикам как GRUB2, как это показывается
ниже:
#cat boot.nasm
;
; Замечание: данный пример написан в синтаксисе Intel Assembly
;
[BITS 16]
[ORG 0x7c00]
boot:
mov al, '!' <<-- Символ для прерывания
mov ah, 0x0e <<-- Отобразить символ
mov bh, 0x00 <<-- Настройка видео режима
mov bl, 0x07 <<-- Очистка/прокрутка экранавниз
int 0x10 <<--- прерывание 10 BIOS который получает входные данные из al, ah, bh, bl
jmp $
times 510-($-$$) db 0 <<--- Из 512 байт первые 510 байт заполнены нулями.
В реальном мире они будут заполнены начальной самораскруткой grub.
db 0x55 <<-- &
db 0xaa <<-- | сообщает BIOS что это устройство активно/с подписью fdisk/флагом запуска.
#nasm -f bin boot.nasm && qemu-system-x86_64 boot
Это сделает некий загрузочный диск запуска (образ диска) из файла boot.nasm
и он станет некими входными данными для qemu
, который и выполнит его. Как
вы можете видеть на
Рисунке 3-30,
вы обнаружите напечатанным на экране !
.
В целом наша машина qemu
рассматривает
boot
в качестве некого диска и всякий раз когда эта машина
qemu
завершает свою стадию BIOS, этот BIOS проваливается в самые первые 512
байт нашего диска boot
. Здесь мы обнаруживаем, что самые первые 510 байт
заполнены 0, а в последних 2 байтах мы имеем !
(наш начальный загрузчик) и он
будет выведен на печать на нашем экране.
На данный момент мы получили хороший обзор GRUB; теперь мы намерены пройти в своём следующем разделе дальше, где мы обсудим что на самом деле происходит внутри GRUB 2/
На момент написания этой книги самым последним доступным исходным кодом GRUB был GRUB 2.04, которым я и
воспользовался здесь. Исполняемый файл начальной самораскрутки (когда наша система основана на BIOS) из самых
первых 440 байт именуется boot.img
, который доступен в
/usr/lib/grub/i386-pc/boot.img
.
# ls -lh /usr/lib/grub/i386-pc/boot.img
-rw-r--r--. 1 root root 512 Mar 28 2019 /usr/lib/grub/i386-pc/boot.img
# file /usr/lib/grub/i386-pc/boot.img
/usr/lib/grub/i386-pc/boot.img: DOS/MBR boot sector
Этот файл boot.img
создан из того исходного кода, который записан в файле
/GRUB 2.04/grub-core/boot/i386/pc/boot.S
.
Ниже приводится фрагмент его кода:
<snip>
1 /* -*-Asm-*- */
2 /*
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 1999,2000,2001,2002,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
5 *
6 * GRUB is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * GRUB is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <grub/symbol.h>
21 #include <grub/machine/boot.h>
22
23 /*
24 * defines for the code go here
25 */
26
27 /* Print message string */
28 #define MSG(x) movw $x, %si; call LOCAL(message)
29 #define ERR(x) movw $x, %si; jmp LOCAL(error_message)
30
31 .macro floppy
32 part_start:
33
34 LOCAL(probe_values):
35 .byte 36, 18, 15, 9, 0
36
37 LOCAL(floppy_probe):
38 pushw %dx
39 /*
40 * Perform floppy probe.
41 */
42 #ifdef __APPLE__
43 LOCAL(probe_values_minus_one) = LOCAL(probe_values) - 1
44 movw MACRO_DOLLAR(LOCAL(probe_values_minus_one)), %si
45 #else
46 movw MACRO_DOLLAR(LOCAL(probe_values)) - 1, %si
47 #endif
48
49 LOCAL(probe_loop):
50 /* reset floppy controller INT 13h AH=0 */
51 xorw %ax, %ax
52 int MACRO_DOLLAR(0x13)
</snip>
Вы можете рассматривать boot.img
как некую первую стадию или Часть 1 GRUB.
Этот файл boot.img
передаёт управление в
diskboot.img
, который выступает Частью 2 GRUB.
# ls -lh /usr/lib/grub/i386-pc/diskboot.img
-rw-r--r--. 1 root root 512 Mar 28 2019 /usr/lib/grub/i386-pc/diskboot.img
# file /usr/lib/grub/i386-pc/diskboot.img
/usr/lib/grub/i386-pc/diskboot.img: data
Этот файл diskboot.img
сделан из исходного кода
grub-2.04/grub-core/boot/i386/pc/diskboot.S
.
Ниже приводится некий фрагмент его кода:
<snip>
1 /*
2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 1999,2000,2001,2002,2006,2007,2009,2010 Free Software Foundation, Inc.
4 *
5 * GRUB is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * GRUB is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include <grub/symbol.h>
20 #include <grub/machine/boot.h>
21
22 /*
23 * defines for the code go here
24 */
25
26 #define MSG(x) movw $x, %si; call LOCAL(message)
27
28 .file "diskboot.S"
29
30 .text
31
32 /* Tell GAS to generate 16-bit instructions so that this code works
33 in real mode. */
34 .code16
35
36 .globl start, _start
37 start:
38 _start:
39 /*
40 * _start is loaded at 0x8000 and is jumped to with
41 * CS:IP 0:0x8000 in kernel.
42 */
</snip>
Наш файл diskboot.img
загружает затем реальную часть ядра GRUB 2, которая
составляет Часть 3 GRUB. Вы также можете рассматривать Часть 3 GRUB является неким ядром всего начального загрузчика.
На этом этапе GRUB 2 будет способен выполнять чтение из своей файловой системы.
# ls /boot/grub2/i386-pc/core.img -lh
-rw-r--r--. 1 root root 30K Dec 9 10:18 /boot/grub2/i386-pc/core.img
В /GRUB 2.00/grub-core/kern/main.c
GRUB 2 настраивает значение имени корневого
устройства, считывает grub.cfg
и его конец показывает имеющийся перечень
операционных систем для выбора.
Я надеюсь что теперь вы разобрались как работает GRUB 2. Ниже приводится быстрое краткое изложение того что мы обсуждали на данный момент:
-
Начальный загрузчик это самый первый код, запускаемый после встроенного ПО.
-
Начальный загрузчик/ GRUB копирует своё ядро в оперативную память.
-
Этот начальный загрузчик загружает в оперативную память соответствующий образ initramfs и передаёт своему ядру указатель на него.
-
Начальный загрузчик отдаёт управление своему ядру.