Восстановление загрузки с EFI в Lenovo G580

Все началось с того, что я приобрел ноутбук Lenovo G580.
А так как найти сейчас ноутбук без EFI практически нереально, то и мой экземпляр предлагал такой вариант работы.
Возможность работы в режиме совместимости в настройках была, но если есть прекрасная возможность прикоснуться к новым технологиям, то почему бы ей и не воспользоваться, поэтому это вариант был безжалостно выключен.
И с этого момента начались мои приключения.

Винчестер был разбит в GPT и по всем правилам сначала был установлен Windows 7. После установки в меню загрузки, которое можно вызвать во время включения питания, помимо списка устройств, с которых можно загрузиться, появилась и строчка 'Boot Microsoft Windows', поставленная по умолчанию.

Далее был установлен Arch Linux. Загрузочный образ этого дистрибутива может работать и из-под EFI без эмуляции поведения BIOS. Дистрибутив был поставлен, grub-efi был установлен на загрузочный раздел EFI, осталось только добавить его в меню загрузки системы.

Для внесения изменений в порядок загрузки под Linux существует утилита efibootmgr, позволяющая создавать новые, изменять и удалить существующие записи, а так же изменять порядок загрузки. Т.к. раньше я с EFI дело не имел, то вывод утилиты с указанием на отсутствие каких либо записей вообще меня не насторожил. И, как оказалось, зря. Следуя руководству я добавил свою загрузочную запись, указывающую на установленный Grub и перегрузился. Да, запись позволяющая грузить Grub появилась в списке загрузки, после чего я решил добавить еще и запись для Windows. Загрузившись в Linux, меня опять не насторожило, что записей о порядке загрузки опять нет, и я прошел уже изведанным путем добавив заново запись для Grub, а затем и для Windows.

После перезагрузки внезапно выяснилось что ни вход в настройки BIOS ни вызов меню загрузки больше не работают. При любых действиях грузиться однозначно Grub. Мне повезло, я остался с более-менее работоспособной системой, хоть и лишенной возможности грузиться с других источников, кроме как с системного раздела.

В самом начале экспериментов я с помощью EasyBCD легким движением мыши уничтожил все записи в bcd и Windows стал недоступен. Что в принципе не сильно и помешало дальнейшим изысканиям, т.к. утилит для работы с EFI я все равно не нашел, а Lenovo не предоставляет никаких утилит для восстановления образа BIOS для моего ноутбука, ни даже самого образа. Все дальнейшие работы проводились в Linux, который собственно и является моей основной рабочей системой.
Т.к. ноутбук нужен постоянно, каких то критических по отношению к системе действий старался не производить.
Поиск в интернете выявил похожую проблему у многих людей, не только с моим ноутбуком и в основном они сводились к тому, что после установки Ubuntu система либо не грузилась полностью, либо как в моем случае грузился лишь Grub. Решений не было. Далее на форуме Lenovo нашел похожие проблемы у людей с моделью моего ноутбука. Там вообще все решалось заменой материнской платы по гарантии, что мне совсем не подходило.

Информации в интернете о EFI не так уж и много. В основном это Wiki Tianocore на SF, где можно скачать EFI Shell и EDK, раздел на сайте Intel, на котором информации практически нет, сайт UEFI Forum, на котором можно взять спецификации на EFI, и мелкие крупицы информации выискиваемые с помощью Google.

На установочном диске Arch Linux идет две версии EFI Shell, одна универсальная, для версий начиная с 1.x, другая для версий начиная с 2.31. Заработала только универсальная версия, хотя система говорила что она версии 2.31 от Phoenix. Это был существенный минус, т.к. новая версия содержала в себе утилиту bcfg, которая предназначена для манипулирования загрузочными записями.

После прочтения спецификации на EFI выяснилась картина работы EFI BootManager. Вкратце это выглядит так: BootManager ищет в NVRAM записи которые говорят что грузить. Это могут быть как устройства, так и программы-загрузчики, находящиеся как в памяти, так и на диске. Есть переменная которая отвечает за порядок загрузки, говоря BootManager`у что в каком порядке грузить, если предыдущий пункт не удался. Есть и переменная, которая однозначно говорит что загружать при следующем запуске. С этими переменными есть нюанс в G580, если ноутбук ранее ушел в hibernate, то весь порядок просто игнорируется. Какой пункт при этом загружается, я не знаю, т.к. у меня всегда загружается только Grub без вариантов. А есть и очень неоднозначное решение для горячих клавиш при загрузке системы. Создается запись, в которой указывается на нажатие какой клавиши реагировать и указывается ссылка на загрузочную запись BootManager`а, для которой вычисляется сигнатура, и в дальнейшем, при нажатии этой клавиши, сигнатура сравнивается с существующей записью, и, если она совпадает, то загрузка идет с нее.

На самый крайний случай, когда записей либо нет, либо они все завершились с ошибкой BootManager пытается найти и загрузить файл bootx64.efi на системном разделе EFI и находящимся в EFI\BOOT\
Далее я выяснил две вещи: 1) по какой-то причине вызов функции по перечислению переменных из EFI ядром Linux возвращает ошибку и
2) Перезаписаны мною первые три загрузочные записи в NVRAM, а записи для различных устройств, вроде CD-привода и сетевой карты остались.

С первым пунктом я так и не разобрался, у меня не столь большие познания в linux kernel hacking, что бы выяснить почему ядро себя так ведет. Загадочности добавляет и тот факт, что часть функций по созданию и установке переменных работают нормально. Но тем не менее это приводит к печальным последствиям при использовании efibootmgr, который не видя существующих записей, по команде создает их начиная с 0, затирая существующие.

Второй пункт показал, что записи для вызова настроек BIOS и меню загрузки были под номерами 0 и 1, которые и были успешно переписаны утилитой.

Со вторым пунктом можно жить, вручную выставляя переменную BootNext, для загрузки с CD и сети. С флешки загрузиться не удалось, т.к. запись формируется по видимому динамически при вызове меню загрузки, и имеющаяся не совпадает с реальным железом. Правда остается тот нюанс, что работают только те загрузочные диски, которые знают о EFI.

Научившись грузиться с CD, удалось починить загрузку Windows, которая так и осталась верна себе, без вопросов перезаписав третью запись (что характерно, Windows не пытается добавить себя в конец очереди, а всегда встает на третью), и изменив BootOrder на себя.

Вопрос с восстановлением работоспособности вызова настроек и меню загрузки пока отложен за неимением времени. Тут очень помог бы дамп переменных EFI с рабочего G580, но за неимением такого приходиться искать другие способы. Основным пока остается написание программы, аналогичной bcfg, но позволяющую создавать так же и записи вызывающие исполняемые образы (Images в терминологии EFI).

И как заключение, хотелось бы отметить что у систем с EFI есть критические недоработки, позволяющие достаточно легко привести систему полностью в неработоспособное состояние. А так же высказать некоторую недоуменность Lenovo, которая, в отличие от других производителей, почему то не встроила EFI Shell в прошивку.
Tags:
EFI, Linux, Lenovo G580

You can't comment this post because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author's username will be hidden by an alias.