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

Различия

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

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

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
wiki:uefiboot [2016/02/13 21:34]
Aleksandr SelivanovAleksandr SelivanovAleksandr Selivanov пунктуация, орфография, форматирование
wiki:uefiboot [2019/03/14 14:46] (текущий)
Sly_tom_catSly_tom_catSly_tom_catXubuntu 18.04 (64bit)Don't worry, be happy! [Инициализация синхронизации пунктов загрузки]
Строка 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, который практически не знаю((почти за каждой командой лезу в гугл)), поэтому,​ наверняка,​ задачу можно было решить и более изящно,​ но я приведу тот код, который у меня заработал.
  
 === Конфигурационный файл === === Конфигурационный файл ===
  
-Вписывать фиксированные опции загрузки ядра и 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''​.
  
-<note important>​Если корневой раздел системы расположен на подразделе [[wiki:​btrfs|BTRFS]] (установщик Ubuntu размещает корень на подразделе ''​@''​ btrfs, даже не спрашивая у вас!), то в ''​OPTIONS''​ нужно обязательно указать параметр ''​rootflags=subvol=@'',​ чтобы ядро смогло найти корень.+Если корневой раздел системы расположен на подразделе [[wiki:​btrfs|BTRFS]] (установщик Ubuntu размещает корень на подразделе ''​@''​ btrfs, даже не спрашивая у вас), то в переменную ​''​ROTFLAGS''​ нужно указать параметр ''​rootflags=subvol=@'',​ чтобы ядро смогло найти корень. Если переменная не определена то имя подтома с корнем будет взято из /etc/fstab.
  
-Альтернативно, можно в самой ''​btrfs''​ указать подраздел по умолчанию, и тогда монтирование раздела с BTRFS без указания ​подраздела будет монтировать указанный ​по умолчанию подраздела не пустой виртуальный ​корень, ​в котором подразделы отражены ​как подкаталоги. Сделать это можно ​командой ''​%%btrfs subvolume set-default ​...%%'' ​(детальный ​синтаксис команды стоит посмотреть в man).</​note>​+Дополнительно в конфигурационный файл добавлен параметр 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. Подпись необходима для организации загрузки в режиме Secuure boot. Если пользоваться ядрами из пакета linux-signed-generic,​ то в список ключей db должен быть добавлен сертификат с ключем Canonical (сертификат с этим ключем можно найти [[https://​github.com/​slytomcat/​UEFI-Boot/​tree/​master/​keys|на github]]). А в опцию загрузки должно добавляться ядро с суффиксом "​.efi.signed"​. Если вы организовали подпись ядер своим ключем,​ и решили использовать иной суффикс,​ то в переменную K_SUFFIX нужно будет его прописать. 
 <note important>​Использование пакета linux-signed-generic имеет странный нюанс, ядра из этого пакета,​ почему то, не вызывают триггеры ядра (которые используются в нашем решении для обновления пунктов загрузки UEFI). Поэтому не удаляйте пакет с обычными ядрами (linux-generic) - его ядра при установке/​удалении нужные триггеры активизируют исправно.</​note>​ <note important>​Использование пакета linux-signed-generic имеет странный нюанс, ядра из этого пакета,​ почему то, не вызывают триггеры ядра (которые используются в нашем решении для обновления пунктов загрузки UEFI). Поэтому не удаляйте пакет с обычными ядрами (linux-generic) - его ядра при установке/​удалении нужные триггеры активизируют исправно.</​note>​
 +
 ==== Утилита uefiboot-update ==== ==== Утилита uefiboot-update ====
-Собственно скрипт утилиты располагается в /​usr/​bin/​uefiboot-update,​ его [[https://​github.com/​slytomcat/​UEFI-Boot/​blob/​master/​usr/​bin/​uefiboot-update|код на github]]: 
  
-Код достаточно примитивный: после определения необходимых параметров, сначала мы вычищаем все ​пункты меню с названиями вида "​Ubuntu....", а затем ​добавляем в порядке возрастания версии ядра новые пункты ​меню. Важность ​порядка добавления в том, что ​самый ​последний добавленный пункт становится самым первым в приоритете загрузки. И важно, что ​бы первым в приоритете стояла загрузка самого свежего ядра.+Собственно скрипт утилиты располагается в /​usr/​bin/​uefiboot-update,​ его [[https://​github.com/​slytomcat/​UEFI-Boot/​blob/​master/​usr/​bin/​uefiboot-update|код на GitHub’е]]:​ 
 + 
 +Код достаточно простой:  
 + 
 +Сначала определяем необходимые настройки. После определения необходимых параметров ​по умолчанию код ​читает конфигурационный файла потом параметры командной строки. Таким образом все необходимые настройки берутся из трех ​мест с приоритетом от дефолтов (минимальный приоритет) через конфиг,​ до параметров командной строки (самый высокий приоритет). 
 + 
 +Затем определяются ​версии существующих в /boot ядер и версии указанные в загрузочных записях UEFI. 
 +Сравнивая эти два списка сначала удаляются те загрузочные записи для которых не осталось ядер ​в /boot, а затем добавляются записи для тех ядер из /boot, для ​которых еще не было загрузочных записей UEFI. Порядок добавления ​организован так, что последним добавляется ядро с самой ​новой версией. Это автоматически делает эту запись первой в порядке загрузки, т.е. по умолчанию,​ после установки нового ядра загружаться будет именно оно. Однако если вы ставите более старое ядро руками, то оно будет добавлено ​последним и следующая загрузка будет именно в то ядро, которое ​вы установили ​последним. 
 + 
 +Приоритет загрузки ​конечно можно ​поменять вручную через efibootmgrесли вас не устроил тот ​что, сделала утилита. 
 + 
 +В скрипте предусмотрена автоматическая инициализация ​переменных настройки ROOT, OPTIONS, ROOTFLAGS др., которые обеспечивает работу утилиты без дополнительных настроек в большинстве стандартных ситуаций. Но, например, для настройки загрузки ​системы ​в режиме SecureBoot нужно будет обязательно указать значение переменной K_SUFFIX в файле /​etc/​uefiboot.conf или в параметре командной строки -s. 
 +==== Инициализация синхронизации пунктов загрузки ====
  
-Приоритет конечно можно поменять ​отдельно, но раз уж мы все пункты Ubuntu* зачистили, то и создавать их надо все, а раз так, то создание в нужном порядке избавляет нас от лишних действий по заданию нужного приоритета. +Самый простой способ инициализировать ​синхронизацию --- воспользоваться теми же средствами, которыми пользуется grub для обновление своей конфигурации.
-===== Инициализация ​синхронизации ​пунктов загрузки =====+
  
-Самый простой способ инициализировать синхронизацию - воспользоваться теми ​же средствамикоторыми пользуется grub для обновление своей конфигурации.+Ядро --- это довольно важный компонент системы и на его установку/​удаление завязано немало ​процессов. Для ​того, чтобы упростить процесс взаимодействия ​с процессом изменения версий ядер были предусмотрены триггеры ядра --- это полная аналогия скриптов DEB-пакета: пред/​постинсталляция и пред/постудаление, но лежат они в соответствующих ​папках ''/​etc/​kernel'',​а не в deb-пакете ядра. Таким ​образом, любое приложение,​ которому надо прореагировать ​на появление нового или удаление ​старого ​ядра могут сделать символьные ссылки на свои утилиты из соответствующих каталогов или просто разместить там свои скрипты (собственно именно так ​и поступает grub). Скрипты эти будут автоматически ​вызываться при наступлении событий связанных установкой или удалением ядер.
  
-Ядро - это довольно важный компонент ​системы и на его установку/​удаление завязано немало процессов. Для того, что бы упростить процесс взаимодействия с процессом изменения ​версий ядер были предусмотрены триггеры ядра - это полная аналогия скриптов DEB-пакета:​ пред/пост инсталляция и пред/пост удаление, но лежат они в соответствующих папках ​/​etc/​kernel ​(а не в deb-пакете ядра)Таким образомлюбое приложение,​ которому надо прореагировать ​на появление ​нового или удаление старого ядра могут сделать ​символьные ссылки на свои утилиты из соответствующих каталогов или просто разместить там свои скрипты (собственно именно так и поступает grub). Скрипты эти будут автоматически вызываться при наступлении событий связанных ​установкой или удалением ядер.+Нас будут интересовать каталоги /etc/kernel/​postinst.d ​и /etc/kernel/postrm.d, именно в них мы создадим символьные ссылки на нашу утилиту.
  
-Нас будут интересовать каталоги /​etc/​kernel/​postinst.d и /​etc/​kernel/​postrm.d именно в них мы создадим символьные ссылки на нашу утилиту. 
 <​code>​ <​code>​
 ln -s /​usr/​bin/​uefiboot-update /​etc/​kernel/​postinst.d/​uefiboot-update ln -s /​usr/​bin/​uefiboot-update /​etc/​kernel/​postinst.d/​uefiboot-update
Строка 71: Строка 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>​
  
-Но оказывается,​ этого не всегда достаточно. Любое ядро в репозитории Ubuntu имеет grub в зависимостях (зависимость типа рекомендованные - recommends) и вот, в некоторых случаях,​((В частности если у вас установлен synaptic и в его настройках указано ставить рекомендованные)) grub пытается установится вместе с ядром (причем ставится почему-то grub-pc). Что бы этого не происходило нужно apt дать четкую и постоянную инструкцию не ставить рекомендованные. +Но оказывается,​ этого не всегда достаточно. Любое ядро в репозитории Ubuntu имеет grub в зависимостях (зависимость типа рекомендованные ​--- recommends) и вот, в некоторых случаях,​((В частностиесли у вас установлен synaptic и в его настройках указано ставить рекомендованные)) grub пытается установится вместе с ядром (причем ставится почему-то grub-pc). Чтобы этого не происходилонужно apt дать четкую и постоянную инструкцию не ставить рекомендованные. 
-Сделать это можно записав значение APT::​Install-Recommends "​false";​ в файл (новый) /​etc/​apt/​apt.conf.d/​zz-no-recommends:​+ 
 +Сделать это можнозаписав значение ​''​%%APT::​Install-Recommends "​false";​%%'' ​в файл (новый) ​''​/​etc/​apt/​apt.conf.d/​zz-no-recommends''​: 
 <​code>​ <​code>​
 # echo '​APT::​Install-Recommends "​false";'​ > /​etc/​apt/​apt.conf.d/​zz-no-recommends # echo '​APT::​Install-Recommends "​false";'​ > /​etc/​apt/​apt.conf.d/​zz-no-recommends
 </​code>​ </​code>​
-===== Автоматизированная установка и настройка ===== 
-На github есть [[https://​github.com/​slytomcat/​UEFI-Boot/​blob/​master/​setup.sh|установочно-настроечный скрипт]],​ который выполняет все необходимые подготовительные операции (перемонтирование ESP в /boot), копирует все файлы на нужные места, а также создает нужные ссылки и удаляет загрузчики. Однако я не советую исполнять его бездумно - стоит проверить,​ что команды соответствуют конфигурации вашей системы. 
  
 +==== Финальная настройка ====
 +Теперь осталось запустить утилиту обновления пунктов меню загрузки UEFI 
 +  # uefiboot-update
 +  ​
 +И последний штрих - уменьшение или вовсе обнуление тайм-аута меню загрузки UEFI (обычно,​ значение по умолчанию для этого тайм-аута 5-10 секунд,​ столько нам совсем не нужно
 +  # efibootmgr -t1  # устанавливаем тайм-аут в 1 секунду
 +или
 +  # efibootmgr -T   # Вовсе удаляем тайм-аут (в некоторых пршивках лучше установить его в 0, а не удалять) ​
 +==== Автоматизированная установка и настройка ====
  
-====== Плюсы полученного решения ======  +На GitHub’е есть [[https://​github.com/​slytomcat/​UEFI-Boot/​blob/​master/​setup.sh|установочно-настроечный скрипт]], ​который выполняет все необходимые подготовительные операции (перемонтирование ESP в /​boot), ​копирует все файлы на нужные места, а также создает нужные ссылки и удаляет ​загрузчики. Однако я не советую исполнять ​его бездумно --- стоит проверить, что команды соответствуют ​конфигурации вашей системы.
-  ​1. Из процесса загрузки исключены все загрузчики - ядро ОС загружается непосредственно из UEFI. Это ​приводить к не слишком значительномуно, вместе с тем, заметному убыстрению процесса загрузки. +
-  - 2. Как и при использовании GRUB/Shim нет никакой необходимости ​следить ​за обновлениями ядер - при установке нового ядра система автоматически будет загружать его при следующей загрузке.+
  
-====== Минусы такого решения ====== +==== Плюсы полученного решения ====
-Описав ​подробно решение я не могу не упомянуть о некоторых сложностях с которыми можно столкнутся. Ниже перечислены "​тяжелые"​ ситуации,​ с которыми вам, скорее всего, и не придется столкнуться,​ но не упомянуть о них - совершенно не допустимо.\\+
  
-1. Пункты загрузки UEFI доступны из меню самого UEFI, и тут у разных производителей могут быть свои реализации этого меню. Попадаются и такие, которые вообще ничего не показывают или не дают выбора. Это не так критично,​ если у вас первым пунктом правильно прописана загрузка единственной ОС на вашем компьютере,​ но может стать проблемой,​ если вы используете несколько ОС или вам, по какой-то причине,​ нужно загрузится в UFIShell или просто загрузится с более старым ядром (после неудачной установки обновлений,​ например).\\  +  * Из процесса загрузки исключены все загрузчики - ядро ОС загружается непосредственно из UEFI. Это приводит к не слишком значительному,​ но, вместе с тем, заметному убыстрению процесса загрузки (обычно экономия - 0.5 - 1.5 секунды). 
-Есть еще производители,​ которые жестко прописывают один единственный пункт загрузки в UEFI (как ни странно - это ссылка на загрузчик Windows). На таком оборудовании описанное решение можно будет реализовать только с значительными изменениями. В частности из-за такого ограничения нет возможности прописать несколько вариантов загрузки для нескольких версий ядра.\\ +  * Как и при использовании GRUB/Shim нет никакой необходимости следить за обновлениями ядер - при установке нового ядра система автоматически будет загружать его при следующей загрузке. 
-2. Некоторые прошивки UEFI имеют в меню своей конфигурации пункт сбросить настройки,​ и при этом сбрасываются все пункты меню загрузки (как часть настроек). Пользователь может воспользоваться сбросом для сброса неправильных настроек в других пунктах настроек UEFI, а в результате получит не загружающуюся машину. Особо стоит упомянуть про VirtualBox, он при закрытии виртуальной машины просто сбрасывает пункты загрузки и приходится загружать систему вручную через UEFIShell. + 
-<note tip>​Для VirtualBox [[http://​anr-daemon.livejournal.com/​17857.html|есть решение]]:​ необходимо добавить строку ​"fs0:​\EFI\ubuntu\grubx64.efi" ​(или аналогичную) в файл ​"startup.nsh" ​в корне EFI раздела.</​note>​ +==== Минусы такого решения ==== 
-3. И самая ​серьезная опасность - это сбой компьютера на этапе ​записи пунктов загрузки в NVRAM. Запуск утилиты обновления пунктов загрузки осуществляется автоматически при установке нового или сносе старого ядра. Причем так уж реализованы эти триггеры ядра, что порой пункты загрузки обновляются по несколько раз. NVRAM-у не страшна частая запись (это не флеш-память с лимитированным числом циклов записи),​ однако сбой при записи может привести к печальным последствиям. Я умудрился потерять питание на своем нетбуке (у него сдохла батарея и он у меня работает от сети), во время обновления пунктов загрузки UEFI. И нетбук практически "​окирпичился"​ :-\ - загрузить я его смог только через UEFIShell вбивая команды загрузки ядра и его параметров руками. Но на этом неприятности не кончились,​ утилита ​efiboot ​напрочь отказалась записывать пункты загрузки выдавая сообщение,​ что на устройстве недостаточно места!!! Я попробовал удалить ненужные переменные,​ но это не помогло. Гуглеж дал совет загрузить ядро с урезанным лимитом на объем свободного NVRAM (по умолчанию,​ резервируется половина объема NVRAM для совместимости с некоторыми кривыми вариантами реализации UEFI), но перед этим я решил сбросить настройки BIOS/UEFI до фабричных. И о чудо - все заработало! + 
-Анализ ситуации показал,​ что и в этом случае виновата кривизна прошивки UEFI - она не смогла распознать кривую запись переменных в nvram. По стандарту,​ любая кривизна в NVRAM должна восприниматься как сигнал к обнулению NVRAM до factory default. Но моя прошивка не отловила глюки в записях и не обнулила NVRAM с нарушенной внутренней структурой. Справедливости ради надо заметить,​ что я умудрился отловить крайне маловероятную ситуацию сбоя именно в момент записи в NVRAM, которая,​ к тому же, наложилась на кривость в реализации UEFI.  +Описав подробно решение я не могу не упомянуть о некоторых сложностях с которыми можно столкнутся. Ниже перечислены "​тяжелые"​ ситуации,​ с которыми вам, скорее всего, и не придется столкнуться,​ но не упомянуть о них --- совершенно не допустимо. 
-<note tip>​Нужно отметить,​ что большинство неприятностей с UEFI, возникают от кривой реализации UEFI поставщиком оборудования. И эти кривости,​ так или иначе, но вылезают боком для //​любых//​ ОС или загрузчиков,​ использующих UEFI.</​note>​+ 
 +  * Пункты загрузки UEFI доступны из меню самого UEFI, и тут у разных производителей могут быть свои реализации этого меню. Попадаются и такие, которые вообще ничего не показывают или не дают выбора. Это не так критично,​ если у вас первым пунктом правильно прописана загрузка единственной ОС на вашем компьютере,​ но может стать проблемой,​ если вы используете несколько ОС или вам, по какой-то причине,​ нужно загрузится в UFIShell или просто загрузится с более старым ядром (после неудачной установки обновлений,​ например). Есть ещё производители,​ которые жёстко прописывают один единственный пункт загрузки в UEFI (как ни странно ​--- это ссылка на загрузчик Windows). На таком оборудовании описанное решение можно будет реализовать только с значительными изменениями. В частности из-за такого ограничения нет возможности прописать несколько вариантов загрузки для нескольких версий ядра. 
 +  ​* ​Некоторые прошивки UEFI имеют в меню своей конфигурации пункт сбросить настройки,​ и при этом сбрасываются все пункты меню загрузки (как часть настроек). Пользователь может воспользоваться сбросом для сброса неправильных настроек в других пунктах настроек UEFI, а в результате получит не загружающуюся машину. Особо стоит упомянуть про VirtualBox, он при закрытии виртуальной машины просто сбрасывает пункты загрузки и приходится загружать систему вручную через UEFIShell. 
 +<note tip>​Для VirtualBox [[http://​anr-daemon.livejournal.com/​17857.html|есть решение]]:​ необходимо добавить строку ​''​fs0:​\EFI\ubuntu\grubx64.efi'' ​(или аналогичную) в файл ​''​startup.nsh'' ​в корне EFI раздела.</​note>​ 
 +  ​* ​И самая ​неприятная опасность ​--- это сбои при записи пунктов загрузки в NVRAM. Запуск утилиты обновления пунктов загрузки осуществляется автоматически при установке нового или сносе старого ядра. Причем так уж реализованы эти триггеры ядра, что порой пункты загрузки обновляются по несколько раз. NVRAM-у не страшна частая запись (это не флеш-память с лимитированным числом циклов записи),​ однако сбой при записи может привести к печальным последствиям. Я умудрился потерять питание на своем нетбуке (у него сдохла батарея и он у меня работал от сети), во время обновления пунктов загрузки UEFI. И нетбук практически "​окирпичился"​ :-\ --- загрузить я его смог только через UEFIShell вбивая команды загрузки ядра и его параметров руками. Но на этом неприятности не кончились,​ утилита ​efibootmgr ​напрочь отказалась записывать пункты загрузки выдавая сообщение,​ что на устройстве недостаточно места!!! Я попробовал удалить ненужные переменные,​ но это не помогло. Гуглеж дал совет загрузить ядро с урезанным лимитом на объем свободного NVRAM (по умолчанию,​ резервируется половина объема NVRAM для совместимости с некоторыми кривыми вариантами реализации UEFI), но перед этим я решил сбросить настройки BIOS/UEFI до фабричных. Ио чудо, --- всё заработало! 
 + 
 +Анализ ситуации показал,​ что и в этом случае виновата кривизна прошивки UEFI - она не смогла распознать кривую запись переменных в nvram. По стандарту,​ любая кривизна в NVRAM должна восприниматься как сигнал к обнулению NVRAM до factory default. Но моя прошивка не отловила глюки в записях и не обнулила NVRAM с нарушенной внутренней структурой. Справедливости ради надо заметить,​ что я умудрился отловить крайне маловероятную ситуацию сбоя именно в момент записи в NVRAM, которая,​ к тому же, наложилась на кривость в реализации UEFI. 
 + 
 +<note tip>​Нужно отметить,​ что большинство неприятностей с UEFI, возникают от кривых реализаций UEFI. И эти кривости,​ так или иначе, но вылезают боком для //​любых//​ ОС или загрузчиков,​ использующих UEFI.</​note>​
  
 ===== Восстановление сброшенных или искаженных настроек пунктов загрузки UEFI ===== ===== Восстановление сброшенных или искаженных настроек пунктов загрузки UEFI =====
  
  
-==== Если есть возможность загрузиться в UEFIShell====+==== Если есть возможность загрузиться в UEFIShell ====
  
-- грузимся в UEFIShell (либо через консоль настройки UEFI, либо через пункт меню загрузки)\\ +  ​- грузимся в UEFIShell (либо через консоль настройки UEFI, либо через пункт меню загрузки) 
-- переходим в ESP раздел:​ **fs0:** +  - переходим в ESP раздел:​ **fs0:** 
-- набираем буквы **vml** и жмем TAB пока в строке ввода не появится нужное (последнее) ядро, допустим это будет **vmlinuz-3.19.0-23-generic** +  - набираем буквы **vml** и жмем TAB пока в строке ввода не появится нужное (последнее) ядро, допустим это будет **vmlinuz-3.19.0-23-generic** 
-- вводите пробел и начинаете набирать **initr** и снова жмете TAB пока не появится полное имя соотвествующего нашему ядру образа рамдиска. В нашем примере это должно быть **initrd.img-3.19.0-23-generic** +  - вводите пробел и начинаете набирать **initr** и снова жмете TAB пока не появится полное имя соотвествующего нашему ядру образа рамдиска. В нашем примере это должно быть **initrd.img-3.19.0-23-generic** 
-- после этого стрелочками переводим курсов перед **initrd.img-3.19.0-23-generic** и вписываем:​ **root=/​dev/​sda2 ro quiet initrd=** +  - после этого стрелочками переводим курсов перед **initrd.img-3.19.0-23-generic** и вписываем:​ **root=/​dev/​sda2 ro quiet initrd=**\\ Вместо /dev/sda2 - пропишите раздел где у вас корневая ФС. По окончании этих манипуляций у вас будет строка такого вида:\\ **fs0:\> vmlinuz-3.19.0-23-generic root=/​dev/​sda2 ro quiet initrd=initrd.img-3.19.0-23-generic**\\ Жмем Enter и ждем когда загрузится Ubuntu, после чего идем в терминал и выполняем<​code>​
-Вместо /dev/sda2 - пропишите раздел где у вас корневая ФС. По окончании этих манипуляций у вас будет строка такого вида:\\ +
-**fs0:\> vmlinuz-3.19.0-23-generic root=/​dev/​sda2 ro quiet initrd=initrd.img-3.19.0-23-generic**\\ +
-Жмем Enter и ждем когда загрузится Ubuntu, после чего идем в терминал и выполняем +
-<​code>​+
 sudo uefiboot-update sudo uefiboot-update
-</​code>​ +</​code>​Все. Пункты меню UEFI восстановлены.
-Все. Пункты меню UEFI восстановлены.+
  
 ==== Если возможности загрузиться в UEFIShell нет ==== ==== Если возможности загрузиться в UEFIShell нет ====
-Потребуется LiveUSB/CD с образом Ubuntu который может загружаться EFI режиме.\\ + 
-Грузимся с LiveUSB/CD в UEFI режиме.\\ +Потребуется LiveUSB/CD с образом Ubuntu который может загружаться EFI-режиме. 
-Устанавливаем утилиту efibootmgr (пакет утилиты есть на диске, поэтому даже соединение с Internet настраивать не нужно) +  грузимся с LiveUSB/CD в UEFI-режиме. 
-<​code>​+  устанавливаем утилиту efibootmgr (пакет утилиты есть на диске, поэтому даже соединение с Internet настраивать не нужно)<​code>​
 sudo apt-get install efibootmgr sudo apt-get install efibootmgr
 </​code>​ </​code>​
-- Прописываем верный пункт загрузки через утилиту efibootmgr командой типа этой: +  ​- Прописываем верный пункт загрузки через утилиту efibootmgr командой типа этой:<​code>​
-<​code>​+
 sudo efibootmgr -cl vmlinuz-3.19.0-23-generic -u "​root=/​dev/​sda2 ro quiet initrd=initrd.img-3.19.0-23-generic"​ -L Ubuntu sudo efibootmgr -cl vmlinuz-3.19.0-23-generic -u "​root=/​dev/​sda2 ro quiet initrd=initrd.img-3.19.0-23-generic"​ -L Ubuntu
-</​code>​ +</​code>​Версии ядер пропишите свои, как и укажите свой раздел корневой ФC вместо /dev/sda2. После перезагрузки идем в терминал и выполняем<​code>​
-Версии ядер пропишите свои, как и укажите свой раздел корневой ФC вместо /dev/sda2. После перезагрузки идем в терминал и выполняем +
-<​code>​+
 sudo uefiboot-update sudo uefiboot-update
-</​code>​ +</​code>​Всё. Пункты меню UEFI восстановлены. 
-Все. Пункты меню UEFI восстановлены.+ 
 +===== Копилефт =====
  
 +Предложенный набор файлов и решений распространяется под GPL. Берите,​ пользуйтесь,​ изменяйте под себя.
  
-====== Копилефт ​=====+===== Ссылки =====
-Предложенный набор файлов и решений распространяется под GPL - берите пользуйтесь и изменяйте под себя.+
  
-====== Ссылки ======+Проект на 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}}