Различия
Здесь показаны различия между двумя версиями данной страницы.
Предыдущая версия справа и слева Предыдущая версия Следующая версия | Предыдущая версия | ||
wiki:uefiboot [2016/06/15 23:48] [Утилита для обновления меню загрузки UEFI] |
wiki:uefiboot [2019/03/14 14:46] (текущий) [Инициализация синхронизации пунктов загрузки] |
||
---|---|---|---|
Строка 1: | Строка 1: | ||
====== Uefi-Boot ====== | ====== Uefi-Boot ====== | ||
- | <note>English version of this wiki page is available [[https://github.com/slytomcat/UEFI-Boot/wiki|on GitHub]]. | + | <note> Обсуждение на форуме: http://forum.ubuntu.ru/index.php?topic=278844.0 |
- | На GitHub’е есть [[https://github.com/slytomcat/UEFI-Boot/wiki|английская версия этой вики-статьи]]. | + | English version of this wiki page is available [[https://github.com/slytomcat/UEFI-Boot/wiki|on GitHub]]. |
+ | |||
+ | На GitHub’е есть [[https://github.com/slytomcat/UEFI-Boot/wiki|английская версия этой вики-статьи]] (не дословный перевод, а вольное изложение идей). | ||
</note> | </note> | ||
Uefi-Boot --- это простенький проект по организации загрузки Ubuntu на компьютерах с поддержкой UEFI без использования загрузчиков. Здесь описано полноценно работающее решение, но само собой для его реализации на другом компьютере могут потребоваться некоторые изменения. Поэтому я советую пользоваться предложенными командами и файлами вдумчиво, понимая и сверяя все действия в соответствии с вашей конфигурацией и настройками. | Uefi-Boot --- это простенький проект по организации загрузки Ubuntu на компьютерах с поддержкой UEFI без использования загрузчиков. Здесь описано полноценно работающее решение, но само собой для его реализации на другом компьютере могут потребоваться некоторые изменения. Поэтому я советую пользоваться предложенными командами и файлами вдумчиво, понимая и сверяя все действия в соответствии с вашей конфигурацией и настройками. | ||
- | Как было указано [[:uefi|в статье]], UEFI поддерживает мультизагрузку (можно настроить несколько вариантов загрузки, которые выбираются из меню UEFI). Так же было отмечено, что все последние ядра в репозитории Ubuntu собираются с опцией UEFISTUB, которая позволяет загружать ядро непосредственно как EFI-приложение. В разделе [[:uefi#загрузка_ядра_из_uefi|Загрузка ядра из UEFI]] были поверхностно разобраны варианты реализации такой загрузки. | + | Как было указано [[wiki:uefi|в статье]], UEFI поддерживает мультизагрузку (можно настроить несколько вариантов загрузки, которые выбираются из меню UEFI). Так же было отмечено, что все последние ядра в репозитории Ubuntu собираются с опцией UEFISTUB, которая позволяет загружать ядро непосредственно как EFI-приложение. В разделе [[wiki:uefi#загрузка_ядра_из_uefi|Загрузка ядра из UEFI]] были поверхностно разобраны варианты реализации такой загрузки. |
Эта статья посвящена последнему варианту (вариант монтирования ESP раздела как /boot). Здесь мы детально рассмотрим как реализовать этот вариант с автоматическим обновлением пунктов загрузки UEFI при установке новых и удалении старых ядер из системы. | Эта статья посвящена последнему варианту (вариант монтирования ESP раздела как /boot). Здесь мы детально рассмотрим как реализовать этот вариант с автоматическим обновлением пунктов загрузки UEFI при установке новых и удалении старых ядер из системы. | ||
Строка 39: | Строка 41: | ||
==== Утилита для обновления меню загрузки UEFI ==== | ==== Утилита для обновления меню загрузки UEFI ==== | ||
- | Я написал эту утилиту на BASH, который практически не знаю, поэтому, наверняка, задачу можно было решить и более изящно, но я приведу тот код, который у меня заработал. | + | Я написал эту утилиту на BASH, который практически не знаю((почти за каждой командой лезу в гугл)), поэтому, наверняка, задачу можно было решить и более изящно, но я приведу тот код, который у меня заработал. |
=== Конфигурационный файл === | === Конфигурационный файл === | ||
Строка 45: | Строка 47: | ||
Вписывать фиксированные опции загрузки ядра и UUID корневого раздела и прямо в код утилиты, так же, как и полагаться только на автоматическое определение корневого раздела через информацию в ''/etc/fstab'', --- не слишком верное решение, довольно часто возникают ситуации, требующие не-дефолтовых настроек. И каждый раз корректировать скрипт принципиально неправильно. Поэтому настройки можно прописать руками в конфигурационном файле утилиты. Все настройки утилиты хранятся в ''/etc/uefiboot.conf'' ([[https://github.com/slytomcat/UEFI-Boot/blob/master/etc/uefiboot.conf|файл доступен на GitHub’е]])((Я даю тут ссылки на GitHub, т.к. там лежат самые последние, обновлённые версии)). | Вписывать фиксированные опции загрузки ядра и UUID корневого раздела и прямо в код утилиты, так же, как и полагаться только на автоматическое определение корневого раздела через информацию в ''/etc/fstab'', --- не слишком верное решение, довольно часто возникают ситуации, требующие не-дефолтовых настроек. И каждый раз корректировать скрипт принципиально неправильно. Поэтому настройки можно прописать руками в конфигурационном файле утилиты. Все настройки утилиты хранятся в ''/etc/uefiboot.conf'' ([[https://github.com/slytomcat/UEFI-Boot/blob/master/etc/uefiboot.conf|файл доступен на GitHub’е]])((Я даю тут ссылки на GitHub, т.к. там лежат самые последние, обновлённые версии)). | ||
- | Вы можете его создать из любого текстового редактора, запущенного под рутом, или воспользоваться настроечным скриптом (ссылка на который есть в конце статьи). В этом файле вы можете задать ключи загрузки ядра (переменная ''OPTIONS'') и устройство корневого раздела (переменная ''ROOT''). Если этих параметров не задавать, то устройство корневого раздела будет взято из ''/etc/fstab'' (ищется точка монтирования '/'), а ключи загрузки ядра по умолчанию будут взяты ''ro quiet''. | + | Вы можете его создать из любого текстового редактора, запущенного под рутом, или воспользоваться настроечным скриптом (ссылка на который есть в конце статьи). В этом файле вы можете задать ключи загрузки ядра (переменная ''OPTIONS'') и устройство корневого раздела (переменная ''ROOT''). Если этих параметров не задавать, то устройство корневого раздела будет взято из ''/etc/fstab'' (берется устройство с точкой монтирования '/'), а ключи загрузки ядра по умолчанию будут взяты ''ro quiet''. |
- | Если корневой раздел системы расположен на подразделе [[wiki:btrfs|BTRFS]] (установщик Ubuntu размещает корень на подразделе ''@'' btrfs, даже не спрашивая у вас), то в переменную ''ROTFLAGS'' нужно указать параметр ''rootflags=subvol=@'', чтобы ядро смогло найти корень. Если переменная не определена то имая подтома с корнем будет взято из /etc/fctab. | + | Если корневой раздел системы расположен на подразделе [[wiki:btrfs|BTRFS]] (установщик Ubuntu размещает корень на подразделе ''@'' btrfs, даже не спрашивая у вас), то в переменную ''ROTFLAGS'' нужно указать параметр ''rootflags=subvol=@'', чтобы ядро смогло найти корень. Если переменная не определена то имя подтома с корнем будет взято из /etc/fstab. |
Дополнительно в конфигурационный файл добавлен параметр K_SUFFIX --- это необходимо для работы с подписанными ядрами из пакета linux-signed-generic, в котором поставляются ядра с подписью ключом Canonical. Подпись необходима для организации загрузки в режиме Secure boot. Если пользоваться ядрами из пакета linux-signed-generic, то в список ключей db должен быть добавлен сертификат с ключом Canonical (сертификат с этим ключом можно найти [[https://github.com/slytomcat/UEFI-Boot/tree/master/keys|на GitHub’е]]). А в опцию загрузки должно добавляться ядро с суффиксом ''.efi.signed''. Если вы организовали подпись ядер своим ключом, и решили использовать иной суффикс, то в переменную ''K_SUFFIX'' нужно будет его прописать. | Дополнительно в конфигурационный файл добавлен параметр K_SUFFIX --- это необходимо для работы с подписанными ядрами из пакета linux-signed-generic, в котором поставляются ядра с подписью ключом Canonical. Подпись необходима для организации загрузки в режиме Secure boot. Если пользоваться ядрами из пакета linux-signed-generic, то в список ключей db должен быть добавлен сертификат с ключом Canonical (сертификат с этим ключом можно найти [[https://github.com/slytomcat/UEFI-Boot/tree/master/keys|на GitHub’е]]). А в опцию загрузки должно добавляться ядро с суффиксом ''.efi.signed''. Если вы организовали подпись ядер своим ключом, и решили использовать иной суффикс, то в переменную ''K_SUFFIX'' нужно будет его прописать. | ||
Строка 57: | Строка 59: | ||
Собственно скрипт утилиты располагается в /usr/bin/uefiboot-update, его [[https://github.com/slytomcat/UEFI-Boot/blob/master/usr/bin/uefiboot-update|код на GitHub’е]]: | Собственно скрипт утилиты располагается в /usr/bin/uefiboot-update, его [[https://github.com/slytomcat/UEFI-Boot/blob/master/usr/bin/uefiboot-update|код на GitHub’е]]: | ||
- | Код достаточно примитивный: после определения необходимых параметров, сначала мы вычищаем все пункты меню с названиями вида "Ubuntu....", а затем добавляем в порядке возрастания версии ядра новые пункты меню. Важность порядка добавления в том, что самый последний добавленный пункт становится самым первым в приоритете загрузки. И важно, что бы первым в приоритете стояла загрузка самого свежего ядра. | + | Код достаточно простой: |
- | Приоритет конечно можно поменять отдельно, но раз уж мы все пункты Ubuntu* зачистили, то и создавать их надо все, а раз так, то создание в нужном порядке избавляет нас от лишних действий по заданию нужного приоритета. | + | Сначала определяем необходимые настройки. После определения необходимых параметров по умолчанию код читает конфигурационный файл, а потом параметры командной строки. Таким образом все необходимые настройки берутся из трех мест с приоритетом от дефолтов (минимальный приоритет) через конфиг, до параметров командной строки (самый высокий приоритет). |
+ | Затем определяются версии существующих в /boot ядер и версии указанные в загрузочных записях UEFI. | ||
+ | Сравнивая эти два списка сначала удаляются те загрузочные записи для которых не осталось ядер в /boot, а затем добавляются записи для тех ядер из /boot, для которых еще не было загрузочных записей UEFI. Порядок добавления организован так, что последним добавляется ядро с самой новой версией. Это автоматически делает эту запись первой в порядке загрузки, т.е. по умолчанию, после установки нового ядра загружаться будет именно оно. Однако если вы ставите более старое ядро руками, то оно будет добавлено последним и следующая загрузка будет именно в то ядро, которое вы установили последним. | ||
+ | |||
+ | Приоритет загрузки конечно можно поменять вручную через efibootmgr, если вас не устроил тот что, сделала утилита. | ||
+ | |||
+ | В скрипте предусмотрена автоматическая инициализация переменных настройки ROOT, OPTIONS, ROOTFLAGS др., которые обеспечивает работу утилиты без дополнительных настроек в большинстве стандартных ситуаций. Но, например, для настройки загрузки системы в режиме SecureBoot нужно будет обязательно указать значение переменной K_SUFFIX в файле /etc/uefiboot.conf или в параметре командной строки -s. | ||
==== Инициализация синхронизации пунктов загрузки ==== | ==== Инициализация синхронизации пунктов загрузки ==== | ||
Строка 74: | Строка 82: | ||
</code> | </code> | ||
- | Теперь пункты загрузки UEFI будут автоматически обновляться после установки нового ядра или после удаления одного из ранее установленных. | + | Теперь пункты загрузки UEFI будут автоматически обновляться после установки нового ядра или после удаления одного из ранее установленных. А если изменений в версиях ядер и их количестве не было, то утилита ничего не будет менять. |
==== Подчистим систему ==== | ==== Подчистим систему ==== | ||
- | Т. к. мы настроили все для загрузки без GRUB/Shim, то необходимо вычистить все, что связано с этими загрузчиками из системы (GRUB может напакастить при обновлении в пунктах меню UEFI): | + | Т. к. мы настроили все для загрузки без GRUB/Shim, то необходимо вычистить все, что связано с этими загрузчиками из системы (при обновлении GRUB будет создавать свою запись в пунктах меню UEFI): |
<code> | <code> | ||
- | # apt-get purge grub* shim | + | # apt-get purge grub* shim os-prober |
</code> | </code> | ||
Строка 92: | Строка 99: | ||
</code> | </code> | ||
+ | ==== Финальная настройка ==== | ||
+ | Теперь осталось запустить утилиту обновления пунктов меню загрузки UEFI | ||
+ | # uefiboot-update | ||
+ | | ||
+ | И последний штрих - уменьшение или вовсе обнуление тайм-аута меню загрузки UEFI (обычно, значение по умолчанию для этого тайм-аута 5-10 секунд, столько нам совсем не нужно | ||
+ | # efibootmgr -t1 # устанавливаем тайм-аут в 1 секунду | ||
+ | или | ||
+ | # efibootmgr -T # Вовсе удаляем тайм-аут (в некоторых пршивках лучше установить его в 0, а не удалять) | ||
==== Автоматизированная установка и настройка ==== | ==== Автоматизированная установка и настройка ==== | ||
Строка 98: | Строка 113: | ||
==== Плюсы полученного решения ==== | ==== Плюсы полученного решения ==== | ||
- | * Из процесса загрузки исключены все загрузчики - ядро ОС загружается непосредственно из UEFI. Это приводит к не слишком значительному, но, вместе с тем, заметному убыстрению процесса загрузки. | + | * Из процесса загрузки исключены все загрузчики - ядро ОС загружается непосредственно из UEFI. Это приводит к не слишком значительному, но, вместе с тем, заметному убыстрению процесса загрузки (обычно экономия - 0.5 - 1.5 секунды). |
* Как и при использовании GRUB/Shim нет никакой необходимости следить за обновлениями ядер - при установке нового ядра система автоматически будет загружать его при следующей загрузке. | * Как и при использовании GRUB/Shim нет никакой необходимости следить за обновлениями ядер - при установке нового ядра система автоматически будет загружать его при следующей загрузке. | ||
Строка 108: | Строка 123: | ||
* Некоторые прошивки UEFI имеют в меню своей конфигурации пункт сбросить настройки, и при этом сбрасываются все пункты меню загрузки (как часть настроек). Пользователь может воспользоваться сбросом для сброса неправильных настроек в других пунктах настроек UEFI, а в результате получит не загружающуюся машину. Особо стоит упомянуть про VirtualBox, он при закрытии виртуальной машины просто сбрасывает пункты загрузки и приходится загружать систему вручную через UEFIShell. | * Некоторые прошивки UEFI имеют в меню своей конфигурации пункт сбросить настройки, и при этом сбрасываются все пункты меню загрузки (как часть настроек). Пользователь может воспользоваться сбросом для сброса неправильных настроек в других пунктах настроек UEFI, а в результате получит не загружающуюся машину. Особо стоит упомянуть про VirtualBox, он при закрытии виртуальной машины просто сбрасывает пункты загрузки и приходится загружать систему вручную через UEFIShell. | ||
<note tip>Для VirtualBox [[http://anr-daemon.livejournal.com/17857.html|есть решение]]: необходимо добавить строку ''fs0:\EFI\ubuntu\grubx64.efi'' (или аналогичную) в файл ''startup.nsh'' в корне EFI раздела.</note> | <note tip>Для VirtualBox [[http://anr-daemon.livejournal.com/17857.html|есть решение]]: необходимо добавить строку ''fs0:\EFI\ubuntu\grubx64.efi'' (или аналогичную) в файл ''startup.nsh'' в корне EFI раздела.</note> | ||
- | * И самая серьезная опасность --- это сбой компьютера на этапе записи пунктов загрузки в NVRAM. Запуск утилиты обновления пунктов загрузки осуществляется автоматически при установке нового или сносе старого ядра. Причем так уж реализованы эти триггеры ядра, что порой пункты загрузки обновляются по несколько раз. NVRAM-у не страшна частая запись (это не флеш-память с лимитированным числом циклов записи), однако сбой при записи может привести к печальным последствиям. Я умудрился потерять питание на своем нетбуке (у него сдохла батарея и он у меня работает от сети), во время обновления пунктов загрузки UEFI. И нетбук практически "окирпичился" :-\ --- загрузить я его смог только через UEFIShell вбивая команды загрузки ядра и его параметров руками. Но на этом неприятности не кончились, утилита efiboot напрочь отказалась записывать пункты загрузки выдавая сообщение, что на устройстве недостаточно места!!! Я попробовал удалить ненужные переменные, но это не помогло. Гуглеж дал совет загрузить ядро с урезанным лимитом на объем свободного NVRAM (по умолчанию, резервируется половина объема NVRAM для совместимости с некоторыми кривыми вариантами реализации UEFI), но перед этим я решил сбросить настройки BIOS/UEFI до фабричных. И, о чудо, --- всё заработало! | + | * И самая неприятная опасность --- это сбои при записи пунктов загрузки в NVRAM. Запуск утилиты обновления пунктов загрузки осуществляется автоматически при установке нового или сносе старого ядра. Причем так уж реализованы эти триггеры ядра, что порой пункты загрузки обновляются по несколько раз. NVRAM-у не страшна частая запись (это не флеш-память с лимитированным числом циклов записи), однако сбой при записи может привести к печальным последствиям. Я умудрился потерять питание на своем нетбуке (у него сдохла батарея и он у меня работал от сети), во время обновления пунктов загрузки UEFI. И нетбук практически "окирпичился" :-\ --- загрузить я его смог только через UEFIShell вбивая команды загрузки ядра и его параметров руками. Но на этом неприятности не кончились, утилита efibootmgr напрочь отказалась записывать пункты загрузки выдавая сообщение, что на устройстве недостаточно места!!! Я попробовал удалить ненужные переменные, но это не помогло. Гуглеж дал совет загрузить ядро с урезанным лимитом на объем свободного NVRAM (по умолчанию, резервируется половина объема NVRAM для совместимости с некоторыми кривыми вариантами реализации UEFI), но перед этим я решил сбросить настройки BIOS/UEFI до фабричных. И, о чудо, --- всё заработало! |
Анализ ситуации показал, что и в этом случае виновата кривизна прошивки UEFI - она не смогла распознать кривую запись переменных в nvram. По стандарту, любая кривизна в NVRAM должна восприниматься как сигнал к обнулению NVRAM до factory default. Но моя прошивка не отловила глюки в записях и не обнулила NVRAM с нарушенной внутренней структурой. Справедливости ради надо заметить, что я умудрился отловить крайне маловероятную ситуацию сбоя именно в момент записи в NVRAM, которая, к тому же, наложилась на кривость в реализации UEFI. | Анализ ситуации показал, что и в этом случае виновата кривизна прошивки UEFI - она не смогла распознать кривую запись переменных в nvram. По стандарту, любая кривизна в NVRAM должна восприниматься как сигнал к обнулению NVRAM до factory default. Но моя прошивка не отловила глюки в записях и не обнулила NVRAM с нарушенной внутренней структурой. Справедливости ради надо заметить, что я умудрился отловить крайне маловероятную ситуацию сбоя именно в момент записи в NVRAM, которая, к тому же, наложилась на кривость в реализации UEFI. | ||
- | <note tip>Нужно отметить, что большинство неприятностей с UEFI, возникают от кривой реализации UEFI поставщиком оборудования. И эти кривости, так или иначе, но вылезают боком для //любых// ОС или загрузчиков, использующих UEFI.</note> | + | <note tip>Нужно отметить, что большинство неприятностей с UEFI, возникают от кривых реализаций UEFI. И эти кривости, так или иначе, но вылезают боком для //любых// ОС или загрузчиков, использующих UEFI.</note> |
===== Восстановление сброшенных или искаженных настроек пунктов загрузки UEFI ===== | ===== Восстановление сброшенных или искаженных настроек пунктов загрузки UEFI ===== | ||
Строка 147: | Строка 162: | ||
Проект на GitHub’е: https://github.com/slytomcat/UEFI-Boot | Проект на GitHub’е: https://github.com/slytomcat/UEFI-Boot | ||
+ | |||
+ | English Wiki: https://github.com/slytomcat/UEFI-Boot/wiki | ||
{{tag>uefi boot}} | {{tag>uefi boot}} |