Uefi-Boot Сравнение версий

Различия

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

Ссылка на это сравнение

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
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}}