вторник, 1 июня 2010 г.

Grub 2 (part 1)

I. GRUB2 - первые шаги.
при первом сравнении grub2 со старым grub самым весомым различием оказывается измененная структура файлов конфигурации. настройка grub2 производится теперь по принципиально иному принципу.
первое же, что бросается в глаза - отсутствие привычного многим "/boot/grub/menu.lst", в котором были прописаны пункты загрузки, таймаут меню и прочие настройки. где это теперь?
в grub2 основным файлом конфигурации является "/boot/grub/grub.cfg". однако же, не торопитесь править его так, как привыкли это делать с "menu.lst". при внимательном прочтении мы видим в начале файла "grub.cfg" такие строки:
Код:
#
# DO NOT EDIT THIS FILE
#
# It is automatically generated by /usr/sbin/grub-mkconfig using templates
# from /etc/grub.d and settings from /etc/default/grub
#
и об этом нас предупреждают не просто так. ведь "grub.cfg" генерируется автоматически с использованием нескольких скриптов. поэтому после следующего обновления grub2 ваш "grub.cfg" будет создан заново, и все ваши правки будут утрачены. но это мы подробнее рассмотрим чуть ниже.
перейдем к основным файлам конфигурации grub2. как и упомянуто выше, главным файлом, собственно, отвечающим за загрузочное меню, является "/boot/grub/grub.cfg". кроме него имеются файл "/etc/default/grub" и папка "/etc/grub.d". рассмотрим их подробнее.

/etc/default/grub
данный файл содержит в себе основные настройки для grub2. через него, собственно, они и изменяются. для наглядности ниже приводится примерное содержимое этого файла:
Код:
GRUB_DEFAULT=6
#GRUB_HIDDEN_TIMEOUT=0
GRUB_HIDDEN_TIMEOUT_QUIET=true
GRUB_TIMEOUT="2"
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
GRUB_CMDLINE_LINUX=""

# Uncomment to disable graphical terminal (grub-pc only)
#GRUB_TERMINAL=console

# The resolution used on graphical terminal
# note that you can use only modes which your graphic card supports via VBE
# you can see them in real GRUB with the command `vbeinfo'
#GRUB_GFXMODE=640x480

# Uncomment if you don't want GRUB to pass "root=UUID=xxx" parameter to Linux
#GRUB_DISABLE_LINUX_UUID=true

# Uncomment to disable generation of recovery mode menu entrys
#GRUB_DISABLE_LINUX_RECOVERY="true"
мы видим, что файл представляет из себя набор опций в человекопонятном формате ОПЦИЯ=ЗНАЧЕНИЕ. мы не будем здесь рассматривать все представленные параметры, поскольку рядовому пользователю вполне достаточно понимания пары-тройки основных параметров.
наиболее часто встречающаяся потребность при настройке grub - изменение стандартного пункта загрзки и/или времени показа меню. рассмотрим же, как это делается.

изменение стандартного пункта загрузки.
по умолчанию стандартный пункт (выделенный при показе меню) - верхний в списке. после установки Ubuntu она окажется наверху, а Windows, например, будет последним пунктом. после обновления ядра первым пунктом списка становится загрузка с новым ядром. это происходит потому, что именно первый пункт загрузки является стандартным по умолчанию.
за это, собственно, отвечает параметр "GRUB_DEFAULT". значением его является номер пункта в меню загрузки, который должен быть выбран стандартным. причем нумерация начинается с нуля. значение по умолчанию - 0, поэтому и выбирается первый пункт. для того. чтобы выбрать другой пункт, нам нужно узнать, каким по счету он будет в списке. тут есть два варианта: просмотреть содержимое "/boot/grub/grub.cfg" и сосчитать, какой по счету окажется нужная запись, или же перезагрузиться и более наглядно посмотреть то же самое в меню загрузки (перед этим побегайте стрелочками по меню, чтобы остановить таймер). вторый вариант отличается более наглядным представлением, что проще для неопытного пользователя. в обоих случаях не забывайте о порядке нумерации - 0, 1, 2, 3 и так далее. то есть, пятому сверху пункту будет соответствовать знаение 4, второму - 1, первому - 0. в вышеприведенном примере установлено значение 6, то есть стандартным задан седьмой пункт меню.
кроме задания конкретного пункта есть еще другие интересный варианты. например, в качестве значения можно указать "saved" - тогда при загрузке будет выбран тот пункт, который был загружен в прошлый раз.
или же можно указать точное название пункта. в данном случае оно должно быть именно таким, каким мы его видим в "/boot/grub/grub.cfg". при этом значение должно указываться в кавычках! данный способ удобен тем, что после обновления ядра не придется изменять настройки из-за съехавшей нумерации
(Кликните, чтобы показать/скрыть)

изменение времени отображения меню.
по умолчанию меню загрузки отображается 10 секунд, после чего загружается стандартный пункт (если раньше не нажат enter и не выбран другой пункт, что останавливает таймер). с изменением задержки все совсем просто.
за эту задержку отвечает параметр "GRUB_TIMEOUT" (не путайте с "GRUB_HIDDEN_TIMEOUT"!). значение задается в секундах. обратите внимание, что цифра указывается в кавычках. в нашем примере это значение - 2, то есть меню отображается две секунды.
кроме того, есть одна хитрость. если поставить значение "-1", то меню будет отображаться до тех пор, пока пользователь не выберет какой-либо пункт. то есть без всяких таймеров и утекающих секунд.

"скрытое" меню.
в случае, если на компьютере установлена только Ubuntu, меню загрузки по умолчанию не будет отображаться, а grub2 будет загружать вас напрямую в систему. однако же, иногда может возникнуть необходимость загрузиться с другим ядром или же запустить проверку памяти. для этого предусмотрено "скрытое меню".
за него отвечает параметр "GRUB_HIDDEN_TIMEOUT". в случае, когда установлены другие ОС, этот параметр закомментирован (# в начале строки). в случае с единственной ОС он будет активен. значение его задает задержку в секундах. grub2 приостановит загрузку на заданное количество секунд, давая пользователю возможность вызвать меню загрузки, нажав Escape.
если значение установлено в 0, то задержки не будет. однако, пользователь все равно сможет вызвать отображение меню, удерживая при загрузке shift.
параметр "GRUB_HIDDEN_TIMEOUT_QUIET" отвечает за отображение таймера во время паузы. при значении "true" таймер показан не будет. "false" - будет отображаться.

изменение стандартных параметров загрузки ядра
иногда бывает необходимо загружать ядро системы с какими-либо особыми параметрами. например, для корректной работы специфического оборудования. в этом случае весьма полезен будет параметр "GRUB_CMDLINE_LINUX_DEFAULT". он отвечает за те параметры, с которыми запускаются linux-ядра при загрузке. значение его по умолчанию - "quiet splash", что приводит показу графической заставки при запуске системы без показа какой-либо текстовой информации. вы можете добавить необходимые вам параметра запуска ядра, приведя это значение к виду "quiet splash your_param1 your_param2", то есть дописав через пробел нужные параметры.
(Кликните, чтобы показать/скрыть)

/etc/grub.d
эта папка содержит в себе скрипты, которые используются при создании "grub.cfg". при обновлении grub2 они находят все установленные на компьютере системы и ядра и формируют в "grub.cfg" меню загрузки, которое мы и видим. два основных из них - "10_linux" и "30_os-prober" отвечают за поиск linux-ядер и остальных ОС на других разделах соотвественно.
файл "40_custom" позволяет добавлять свои пункты загрузки. это может быть полезно, если вы, например, хотите добавить какие-то особые варианты загрузки системы.
(Кликните, чтобы показать/скрыть)
примечание: файл "40_custom" должен заканчиваться пустой строкой, иначе последний пункт не будет отображаться в меню!

применение изменений.
после того, как мы отредактировали и сохранили наши файлы, радоваться еще рано. теперь нужно закончить дело, обновив наш "/boot/grub/grub.cfg". это довольно просто - нужно всего лишь выполнить команду
Код:
sudo update-grub
она выполнит скрипты в папке "/etc/grub.d" и применит заданные в "/etc/default/grub" параметры. после этого смело перезагружаемся и видим, что все работает как надо. ну или не работает...
если все прошло успешно, то в выоде консоли вы увидите спсиок найденных grub2 ОС и linux-ядер. выглядит все это примерно так:

тот же самый "update-grub" происходит и при обновлении ядра.

нюанс с нумерацией дисков и разделов.
в grub2 имеется еще одно важное отличие от старого grub. связано оно с нумерацией жестких дисков и их разделов.
в grub нумерация физических дисков и нумерация разделов начинались одинаково - с нуля. первый физический диск (sda в системе) обозначался "hd0", второй (sdb) - "hd1", и так далее. это же осталось и в grub2.
нумерация же разделов диска изменилась. если в grub первый раздел первого диска (sda1) именовался "hd0,0", четвертый (sda4) - "hd0,3", то теперь, в grub2, цифра раздела в grub2 соотвествует цифре раздела в системе. то есть, sda1 теперь будет "hd0,1" (а не "hd0,0"), sdb4 - "hd1,4".
проще говоря, нумерация дисков идет с нуля, а нумерация разделов - с единицы!

резервная копия.
перед каким-либо редактированием обязательно сделайте бэкап файлов конфигурации. например, выполнив последовательно эти строки:
Код:
datev=$(date +%Y_%m_%d)
mkdir -p ~/.grub.bak/$datev
cd ~/.grub.bak/$datev
mkdir -p boot/grub etc/default
cp /boot/grub/grub.cfg boot/grub
cp -Rp /etc/grub.d etc
cp /etc/default/grub etc/default
(можно сохранить данный скрипт в /usr/bin, назвать, к примеру, "grub-backup" и дать права 755. теперь для резервного копирования grub2 достаточно будет выполнить команду "grub-backup")

II. украшательства.
установка фонового изображения.
вы можете выбрать и установить полноцветное изображение в качестве фона в меню загрузки grub2. размер изображения должен соответствовать разрешению grub2 (по умолчанию - 640x480, задается в "/etc/default/grub"), формат файла - png или tga.
вы можете установить готовый набор из нескольких подходящих для grub2 изображений, выполнив команду
Код:
sudo apt-get install grub2-splashimages
(не путайте пакет grub2-splashimages с пакетом grub-splashimages, который не совместим с grub2!). эти изображения будут помещены в папку "/usr/share/images/grub", которую нужно будет добавить в файл конфигурации (см. ниже).
фоновое изображение задается в файле "/etc/grub.d/05_debian_theme". найдите в нем строку такого вида:
Код:
for i in {/boot/grub,/usr/share/images/desktop-base}/moreblue-orbit-grub.{png,tga} ; do
те, кто более-менее знаком с bash, узнают прием с перечислением в фигурных скобках. для остальных: все на так сложно, как может показаться. в первых фигурных скобках (в нашем примере - "{/boot/grub,/usr/share/images/desktop-base}") перечислены папки, в которых grub2 будет искать подходящие для установки изображения. далее (после слэша) указано имя файла изображения (без расширения!), которое мы хотим установить в качестве фона (здесь - "moreblue-orbit-grub"). вторые фигурные скобки ("{png,tga}") определяют расширения файлов, которые grub2 будет пытаться использовать в качестве фона. заметьте, что пункты в фигурных скобках перечисляются через запятую и не разделяются пробелами!
по умолчанию изображения ищутся в папках "/boot/grub" и "/usr/share/images/desktop-base". изображения из пакета grub2-splashimages у нас распаковались в "/usr/share/images/grub". поэтому мы должны добавить эту папку в список мест, где grub2 будет искать изображения. добавим еще один пункт в первые фигурные скобки.
сразу же определимся с выбором картинки. я выбрал последнюю, переименовав файл для удобства в "winter.tga". заменим имя ("moreblue-orbit-grub") на имя выбранной картинки (в моем случае - "winter"). в итоге получим такую строку:
Код:
for i in {/boot/grub,/usr/share/images/desktop-base,/usr/share/images/grub}/winter.{png,tga} ; do
заметьте, что между именем файла и вторыми фигурными скобками должна стоять точка!
как это работает: grub2 последовательно просматривает заданные папки и ищет в них файл с заданным именем и одним из перечисленных расширений. цикл прекращается как только найдено первое подходящее изображение. таким образом, файл с подходящим именем присутствует в нескольких папках, будет взят файл из той папки, которая раньше указана в списке. аналогично, если изображение представлено в разных форматах (например, "image.png" и "image.tga") - выбран будет файл с тем расширение, которое первым указано во вторых фигурных скобках.
интересности:
  • вы можете добавить любую папку с изображениями, владельцем которой вы являетесь. это упростит добавление/изменение изображений. однако, заметьте: при этом root должен иметь как минимум права r-x на эту папку. также не стоит добавлять папки с шифрованного home-раздела, т.к. на момент загрузки он еще не примонтирован. лучше просто сделайте себя владельцем папки "/usr/share/images/gub" и храните все картинки там.
  • помимо PNG и TGA поддерживается также формат JPEG. но на текущий момент реализована только поддержка jpeg с 8-битным цветом. поэтомуиспользуйте jpeg-файлы только если вы понимаете, что такое глубина цвета и как сохранить изображение в 8-битном цвете. для того, чтобы добавить поддержку jpeg-файлов, приведите вторые фигурные скобки к такому виду: "{png,tga,jpg,jpeg}".

настройка цвета пунктов меню.
цвета пунктов меню также задаются в файле "/etc/grub.d/05_debian_theme". найдите ближе к концу файла следующую секцию:
Код:
if background_image `make_system_path_relative_to_its_root ${bg}` ; then
set color_normal=black/black
set color_highlight=black/light-gray
else
EOF
fi
здесь и настраиваются цвета для пунктов меню загрзки. строка "set color_normal" отвечает за цвета обычного (невыделенного) пункта меню. "set color_highlight" - за цвета выделенного пункта. вот эти две строки мы и будем изменять.
значение каждой из этих строк представляет собой два цвета, разделенные слэшем. первый цвет - это цвет текста. второй цвет - цвет фона строки.
вот список доступных цветов:
(Кликните, чтобы показать/скрыть)
заметьте, что black (черный) при использовании в качестве второго параметра (т.е. цвета фона) в результате даст прозрачный фон, без какой-либо заливки, текст прямо поверх картинки. использование black в качестве цвета текста дает черный текст.
пример:
Код:
set color_normal=black/black
set color_highlight=black/light-gray
в моем случае заданы следующие параметры: обычный пункт - черный текст, прозрачный фон; выделенный пункт - черный текст, серая подсветка строки.
примечание: не перепутайте вышеописанную секцию с секцией "set_mono_theme", что в начале файла! последняя отвечает за цвета меню в том случае, если фоновое изображение отсутствует.

III. восстановление GRUB2.
после, например, установки Windows, вы можете столкнуться с тем, что при загрузке будет отображаться только меню загрузки Windows, а меню grub2 вы не увидите вовсе, что приведет к невозможности загрзуить что-либо кроме Windows. такое происходит из-за того, что Windows при установке затирает загрузочную область жесткого диска (так назывемый MBR-раздел), удаляя оттуда запись загрузчика grub2.
для восстановления grub2 вам понадобится liveCD Ubuntu 9.10 или любой другой современной системы, включающей grub2 в свой дистрибутив. архитектура LiveCD должна соответствовать архитектуре вашей системы! узнать текущую архитектуру можно с помощью команды "arch" или "uname -m". "i686" соответствует 32-битной архитектуре, "amd64" - 64-битной

востановление GRUB2 с LiveCD.
загрузитесь с вашего LiveCD (предварительно выберите меню устройств загрузки при наличии такового или же установите cd-привод первым boot device в BIOS). запустите консоль.
для начала нам нужно будет узнать, на каком диске и на каком разделе установлена Ubuntu. если вы не помните этого - воспользуйтесь командой
Код:
sudo fdisk -l
для работы нам понадобится /-раздел (root). примонтируйте его командой
Код:
sudo mount /dev/sda5 /mnt
в моем случае корневой раздел системы - /dev/sda5, вы же используйте свое значение. если у вас /boot сделан отдельным разделом, его также надо будет примонтировать:
Код:
sudo mount /dev/sda3 /mnt/boot
также монтируем папку /dev нашей live-системы как /dev нашего root-раздела:
Код:
sudo mount --bind /dev /mnt/dev
и папку /proc как /proc root-раздела:
Код:
sudo mount --bind /proc /mnt/proc
теперь выполняем следующую команду:
Код:
sudo chroot /mnt /bin/bash
теперь вы - root-пользователь в системе, корневым разделом которой считается /mnt, то есть корневой раздел вашей настоящей системы. и вот мы готовы обновить MBR-раздел жесткого диска, переустановив grub2. но для начала нам нужно определиться, с какого физического диска загружается наш компьютер. если у вас один жесткий диск, разбитый на разделы - он будет именоваться sda. если несколько - первый из них - sda, второй - sdb, и так далее. если вы не знаете, какой жесткий диск установлен в качестве загрузочного, посмотрите соответствующую опцию в BIOS. обычно жесткий диск указан по модели (например, так: ST9160310AS). чтобы узнать, какому диску в системе соответствует данная модель, выполните такую команду:
Код:
for d in /dev/sd[a-z] ; do echo "$d: $(sudo hdparm -I $d | grep -i 'model')" ; done
кроме того, в Ubuntu 9.10 можно воспользоваться утилитой palimpsest ("система - администрирование - дисковая утилита").
определившись с загрузочным диском (в нашем примере - sda), ставим на него grub2:
Код:
grub-install /dev/sda
если вы столкнетесь с какими-либо ошибками - попробуйте перезапустить команду с ключом --recheck:
Код:
grub-install --recheck /dev/sda
обратите внимание: мы устанавливаем grub2 на физический диск (sda, sdb...), а не на раздел (sda3, sdb1...)!
если все прошло успешно, выходим из chroot командой
Код:
exit
отмонтируем наши диски и папки:
/dev нашей live-системы:
Код:
sudo umount /mnt/dev
/proc live-системы
Код:
sudo umount /mnt/proc
boot-раздел, если таковой монтировался отдельно:
Код:
sudo umount /mnt/boot
и собственно, корневой раздел:
Код:
sudo umount /mnt
все! перезагружаемся, восстанавливаем порядок загрузки в BIOS (ставим жесткий диск на первое место) и смотрим результат.

востановление GRUB2 с LiveCD. способ 2 (без chroot)
нам опять же понадобится LiveCD Ubuntu 9.10 или другой системы с поддержкой grub2. в отличие от предыдущего способа, мы не будем запускать установщик через chroot, что позволит сократить количество требуемых действий.
итак, загружаемся с выбранного LiveCD, запускаем консоль. вместо использования chroot мы воспользуемся ключом "--root-directory". но для начала убедимся, что данная опция поддерживается нашей live-системой. если вы работаете с Ubuntu 9.10 Desktop, можно не волноваться. в ином случае выполните
Код:
grub-install --help
если в описании опций присутствует вышеупомянутый ключ "--root-directory" - все в порядке. теперь нам нужно примонтировать корневой раздел системы. если вы не помните, на каком разделе стоит система, вам поможет
Код:
sudo fdisk -l
определившись с корневым разделом, монтируем его. пусть в нашем примере это будет sda5:
Код:
sudo mount /dev/sda5 /mnt
если у вас выделен отдельный boot-раздел, примонтируйте и его. допустим. это sda2
Код:
sudo mount /dev/sda2 /mnt/boot
теперь переходим собственно к установке grub2. ключ "--root-directory" позволяет указать, что использовать в качестве корневой директории. нам нужен корневой раздел нашей системы, который примонтирован в /mnt. поэтому выполняем:
Код:
sudo grub-install --root-directory=/mnt /dev/sda
как и в предыдущем способе, grub2 устанавливается на физический диск, а не на раздел! в качестве диска нужно указать тот диск, который установлен загрузочным в bios.
если все пройдет успешно, установщик выведет сообщение об успешном завершении и список обнаруженных жестких дисков, которые были добавлены в "device.map". если все это есть - отмонтируем диски, перезагружаемся и радуемся. если будет выведен неполный список дисков - отредактируйте файл "device.map" в корневой папке установленной системы (в описанном примере - "/mnt/boot/grub/device.map") и поправьте его, добавив остальные диски и поправив нумерацию. файл должен иметь вид
Код:
(hd0) /dev/sda
(hd1) /dev/sdb
и так далее для всех жестких дисков. сохраните файл и повторно выполните команду grub-install, как описанно выше. теперь должен отобразиться правильный список дисков. отмонтируем диски и перезагружаемся.

загрузка системы при частичной неработоспособности GRUB2.
в некоторых случаях может оказаться так, что отдельнные файлы grub2 будут повреждены (например, в результате сбоя при выполнение "update-grub"). однако, иногда есть шанс загрузиться в свою систему и восстановить grub2 из нее без необходимости полной переустановки оного.
если при загрузке grub2 вы видите сообщения об ошибках - не спешите предаваться панике. все может быть еще вполне поправимо. на данный момент наша главная цель - попасть в консоль grub2. вы можете сразу увидеть ее на экране, или же будет предложено что-либо нажать или выбрать для запуска консоли. в любом случае, если вам удалось запустить консоль - радуйтесь, шансы на спасение увеличены!
консоль grub2 похожа на более привычную оболочку bash. здесь также поддерживается автодополнение команд по нажатию tab. если же нажать tab в пустой строке - мы увидим полный список доступных команд. что ж, приступим к процедуре запуска системы. для начала нам нужно задать root-раздел, то есть раздел, на который установлена наша система. в моем случае это "/dev/sda5". (в grub2 разделы задаются в виде "hd*,*". если вы мало знакомы с нумерацией разделов в grub2 - почитайте пункт "нюанс с нумерацией дисков и разделов" в I главе). root-раздел задается командой
Код:
set root=(hd0,5)
в моем случае это "hd0,5", он же "/dev/sda5", то есть пятый раздел первого диска. полный список доступных разделов можно получить уже знакомой многим командой "ls". она выдаст что-то вроде
Код:
(hd0,1) (hd0,2) (hd1.1) (hd2,1)
после того, как вы задали root-раздел, можно удостовериться в том, что все получилось, выполнив команду "root". она выдаст сообщение следующего вида:
Код:
(hd0,5): filesystem is ext2
некоторых, наверно, смутит упоминание ext2. не волнуйтесь, так и должно быть (для файловых систем ext2/3/4 в grub2 используется общий драйвер)
после того, как задан root-раздел, мы должны указать, какое ядро следует загрузить. это задается командой "linux". укажите то ядро, с которым вы обычно загружаетесь. в моем случае команда будет выглядеть так:
Код:
linux /boot/vmlinuz-2.6.32-020632rc6-generic root=/dev/sda5
не пугайтесь, если вы не помните номер вашего ядра. просто напишите "linux /boot/vmlinuz" и нажмите tab. на экран будет выведен список доступных ядер.
обратите внимание на параметр "root=/dev/sda5" в конце строки! здесь также нужно указать ваш root-раздел, но уже в более привычном формате. без этого система может не загрузиться.
вместе с ядром следует загрузить initrd (это образ, содержащий все необходимое для определения жесткого диска, монтирования корневой ФС и продолжения зарузки системы). делается это командой "initrd". нужно загрузить initrd-образ, версия которого соответствует версии загружаемого ядра:
Код:
initrd /boot/initrd.img-2.6.32-020632rc6-generic
после этого можно загрузить систему командой
Код:
boot
в результате всех манипуляций мы должны успешно загрузиться в родную систему. а там уже можно выполнить "update-grub" и при необходимости восстановить нужные файлы из резервной копии (которую вы, конечно, делали).
(Кликните, чтобы показать/скрыть)
если же вышеприведенный метод не сработал (ядро не загрузилось или же вы вовсе не можете попасть в консоль grub2) и ничего не загружается - тут уж дело идет к переустановке grub2, что описана выше.
(Кликните, чтобы показать/скрыть)

1 комментарий:

Анонимный комментирует...

А какой смысл тупо копировать руководство откуда-то? :) Можно просто ссылку кинуть. Или тут что-то своё тоже есть?