Как стать автором
Обновить

Восстановление загрузки с 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 в прошивку.
Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.