Журнал LinuxFormat - перейти на главную

LXF100-101:Загрузить незагружаемое

Материал из Linuxformat
Версия от 11:27, 20 марта 2009; Crazy Rebel (обсуждение | вклад)

(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск
Загрузка Как добраться до важных файлов, если Linux не грузится?

Содержание

Когда Linux не загружается

Мысль об этом вгоняет в дрожь пользователей всех ОС - не дай Бог, компьютер откажется загружаться. Д-р Крис Браун прольет бальзам на ваши раны.

Для нас, старых волков, загрузка, или «начальная загрузка» – это та глубоко таинственная последовательность операций, выполняемых компьютером между его включением и выводом приглашения войти в систему. За это время куча непонятных сообщений проплывает по экрану, но обычно пользователи их игнорируют, и большинство дистрибутивов Linux скрывает их за красивым экраном с обнадеживающим прогресс-индикатором. И это замечательно – пока работает. На данном уроке мы рассмотрим процесс загрузки более подробно: в частности, выясним, что может пойти неправильно и как диагностировать и устранить проблему.

Проникаемся проблемой

Когда я преподавал Linux на одном из моих курсов, многие слушатели говорили мне, что интересуются устранением неисправностей в той или иной форме. Некоторые ищут рецептов типа кулинарных – «Увидев сообщение об ошибке X, запустите команду Y», но таким способом устранить неисправность удается редко. Мой первый совет всем тем, кто столкнулся с проблемой, всегда один и тот же: «При устранении неисправности первым делом надо понять, как система должна работать. Вторая важная вещь – точно представить, что система пыталась сделать, когда неисправность возникла».


Помня об этом, взглянем на загрузку Linux. Знание нормальной последовательности событий и установление, как далеко она зашла перед возникновением проблемы, являются ключевыми для диагностики и исправления проблем загрузки. Рисунок 1 справа показывает нормальную последовательность событий (зеленые стрелки) и указывает на некоторые возможные пути неудачи (красные стрелки).

Знакомимся с загрузкой поближе

Загрузка – операция многоступенчатая. При включении компьютера контроль вначале переходит к программе, называемой BIOS, которая хранится в постоянной памяти на материнской плате. BIOS выполняет тестирование оборудования и разведку окрестностей на предмет устройств для загрузки, и выводит экран конфигурации, позволяющий установить порядок поиска загрузочных устройств; в современных BIOS их диапазон весьма широк, в том числе PXE-загрузка с сетевого сервера. На нашем уроке мы рассмотрим только загрузку с жесткого диска.

Затем BIOS считывает главную загрузочную запись (Master Boot Record, MBR) с выбранного устройства и запускает ее. (Не найдя MBR, BIOS выведет сообщение вида «Нет операционной системы» и впадет в полный ступор.) MBR занимает первый сектор диска. Он содержит таблицу разделов (64 байта) и очень короткую (446 байт) программу первичной загрузки, или ‘stage 1’. Этот загрузчик всего-навсего выводит на экран слово Grub и передает эстафету загрузчику второй стадии, используя «карту блоков», внедренную в MBR (карта содержит номера блоков, где находится загрузчик ‘stage 2’). Здесь я подразумеваю, что вы используете загрузчик Grub. Существует также более старый загрузчик Lilo, но Grub «умнее» и используется в большинстве современных дистрибутивов Linux. Второй этап работы загрузчика Grub по сути дела «полуторный», и если вы посмотрите в директории /boot/grub, то увидите там файлы, содержащие различные его варианты, с именами вида e2fs_stage_1_5 и reiserfs_stage_1_5. Каждая из этих программ способна получить доступ к файлам по их имени, используя определенный формат файловой системы. e2fs_stage_1_5 может читать файловые системы ext2 и ext3, reiserfs_stage_1_5 – файловую систему reiser, и т.д. Grub способен обратиться к файлам по их имени во время начальной загрузки (перед запуском Linux), и этим он отличается от Lilo. Программа «полуторного» этапа загружает Grub stage 2, который значительно больше. На этом этапе считывается файл конфигурации Grub (обычно /boot/grub/menu.lst или /boot/grub/grub.conf) и, на основе содержащихся там записей, выводится меню выбора операционных систем для загрузки. Если Grub не может найти свой файл конфигурации, он переходит в интерактивную командную строку, позволяющую ввести команды Grub вручную. Типичное содержание записи menu.lst такое:


title openSUSE 10.2
      root (hd0,0)
      kernel /boot/vmlinuz-2.6.18.2-34-default root=/dev/hda1 vga=0x317 showopts
      initrd /boot/initrd-2.6.18.2-34-default

Первая строчка просто содержит текст, который появится в меню загрузки. Следующие за ней строки содержат команды, которые Grub должен выполнить, если вы выберите этот пункт меню. Строка root подсказывает Grub, где искать корневую файловую систему. У Grub своя система именования разделов диска, отличная от системы, принятой в Linux, что сбивает с толку. На языке Grub hd0 означает первый диск – а на обычном ПК с IDE-дисками это будет ссылка на Linux-устройство /dev/hda, или, на более свежих дистрибутивах, /dev/sda [на самом деле что для grub означает hd0 итд определяется в файле /boot/grub/device.map]. На языке Grub (hd0,0) ссылается на первый раздел этого диска – в Linux это будет /dev/hda1 или /dev/sda1. Строка kernel определяет файл, который Grub должен загрузить как ядро Linux; в конце этой строки вы увидите несколько дополнительных параметров загрузки, передаваемых ядру. Подробнее об этом чуть позже. Строка initrd определяет файл ‘initial RAM Disk’ – образ файловой системы, которая будет использоваться ядром как загрузочная. Grub также отвечает за загрузку его в память. Если Grub не может найти ядро или образ ram-диска, он выводит Error 15: File not found (Ошибка 15: Файл не найден) и останавливается.

Как только ядро стартует, оно монтирует корневую файловую систему с жесткого диска. Имя раздела, содержащего эту файловую систему, передается ядру как параметр, который вы видели в файле menu.lst выше. Монтирование корневой файловой системы – ключевая точка процесса загрузки, и если вы пытаетесь точно определить проблему, жизненно важно выяснить, удалось ли ядру это сделать. Сбой в монтировании файловой системы, как правило, приводит к «панике ядра» [kernel panic], хотя некоторые системы просто зависают. Если же ядро благополучно смонтировало корневую файловую систему, оно создает одиночный процесс (с ID 1), выполняющий программу /sbin/init. Если ядро не может найти init, оно также «паникует» и останавливается или (в зависимости от дистрибутива) выкидывается в командную строку суперпользователя. Да, кстати, придется добавить вам путаницы: Ubuntu больше не использует init, он заменен на upstart.

Init отвечает за запуск скриптов, которые запустят все остальные сервисы в системе. Существует очень важный и достаточно низкоуровневый скрипт, запускаемый init в начале процесса. В Red-Hat-подобных системах это /etc/rc.d/rc.sysinit, в SUSE – /etc/init.d/boot. Среди прочего, этот первичный скрипт последовательно проверяет и монтирует остальные разделы диска, прописанные в /etc/fstab. Хотя, конечно, на этом этапе тоже хватает потенциальных неприятностей, но рассказ о них придется оставить до следующего месяца.

Берем Grub под контроль

Ключевое умение в исправлении проблем загрузки – это знание, как вручную вмешаться в процесс загрузки Grub. Большинство дистрибутивов конфигурируют Grub а выбор пункта меню «по умолчанию», но на короткое время (пару секунд) отображают окно, где вы можете нажать Esc для прерывания процесса и принятия полного контроля над Grub на себя. Обычно это ведет к выходу из заставки Grub в текстовое меню. Здесь, следуя инструкциям на экране, выберите пункт меню и отредактируйте связанные с ним команды перед загрузкой. Можно даже переключиться в командную строку Grub и вводить команды Grub напрямую; например в этом месте вы можете, теоретически, вручную ввести root, kernel и initrd строки из файла menu.lst, который мы рассмотрели ранее. Рис. 2 показывает результат ввода help в командную строку Grub.

Спасательная загрузка

Если все способы «подкрутки» команд в меню загрузки Grub не помогли загрузить систему, может быть, настало время выполнить ‘rescueboot’ [спасательную загрузку], которая означает, что вы должны загрузить Linux с инсталляционного CD или другого «средства спасения». Ядро и его модули загружаются с CD вместе с небольшой файловой системой, хранящейся в памяти. В результате запускается маленький, но работоспособный Linux, не привязанный ни к какой файловой системе на жестком диске. Потом вы можете смонтировать разделы жесткого диска в файловую систему и получить к ним доступ для устранения неполадки. Помогут установочные CD или DVD большинства современных дистрибутивов, так как для восстановления определенного дистрибутива не требуется именно его установочный диск, и вы можете взять любой доступный.

Пользуясь спасательной системой, очень важно иметь ясную голову, потому что файлы на вашем жестком диске окажутся не в тех местах, в которых вы видели их при «реальной» установке. Например, если в спасательной системе смонтировать корневой раздел в /mnt, то файл, обычно видимый в /etc/fstab, нужно будет искать в /mnt/etc/fstab.

Реальная ситуация 1

Наш первый пример касается RHEL5, в котором директория /usr помещена в отдельный раздел. По какой-то причине (забыл, какой) мне пришлось диктовать по телефону, как редактировать /etc/fstab, администратору-новичку, и в строке, отвечающей за монтирование раздела /usr, он закончил поле словами LABEL=/user вместо LABEL=/usr. Эта ошибка приводит к невозможности многопользовательской работы, выкидывая вас в однопользовательскую оболочку. Диалог выглядит примерно так:

fsck.ext3: Unable to resolve ‘LABEL=/user’          [FAILED]
*** An error occurred during the file system check.
*** Dropping you to a shell; the system will reboot
*** when you leave the shell
 Give root password for maintenance (or type Control-D to continue):

Тут главное – действительно прочитать сообщение об ошибке. Почему система пытается найти метку с именем /user? В каком файле это происходит?

Хм... Может быть, /etc/fstab? Так как система любезно вытолкала нас в командную строку root, вы решаете, что можно непосредственно отредактировать /etc/fstab и исправить ошибку. Однако оказывается, что на данном этапе (по милости fsck) корневая файловая система монтируется в режиме «только для чтения», и вы не можете редактировать файлы и записывать изменения. Здесь сработает следующий трюк. Перемонтируем файловую систему в режиме чтения-записи, вот так:

# mount -o remount,rw /

Выполнив это, я смог отредактировать /etc/fstab, исправить ошибку и нормально перезагрузиться.

Реальная ситуация 2

Второй пример сложнее предыдущего, и включает сценарий двойной загрузки.


Сперва я установил OpenSUSE 10.2 на пустой жесткий диск, выделив 8-ГБ раздел hda1 под корневой и 2-ГБ раздел hda2 под раздел подкачки. Установщик немедля прописал загрузчик Grub 1-го этапа в основную загрузочную запись, а загрузчик полуторного этапа – в блоки диска. Немного погодя я установил на свободное место диска Fedora 7, выделив под корневой раздел hda3 те же 8 ГБ и разделив swap-раздел OpenSUSE hda2 между двумя системами. Рис. 3 поможет вам, если вы уже запутались. Я разрешил Fedora установку Grub по умолчанию в /dev/sda (имена отличаются, так как OpenSUSE 10.2 называет разделы традиционно – hda1, hda2 и т.д., а Fedora 7 использует SCSI-стиль именования – sda1, sda2 и т.д.).

При установке Fedora мне было предложено добавить дополнительный пункт в загрузочное меню Grub, и я попросил добавить пункт с названием SUSE 10.2 и именем устройства /dev/sda1. В результате файл конфигурации Grub у Fedora выглядел так:

title SUSE 10.2
      rootnoverify (hd0,0)
      chainloader +1

Если я выбираю этот пункт меню, Grub Fedora должен начать загрузку Grub OpenSUSE с первого сектора первого раздела (который Grub называет (hd0,0)), Fedora7 – /dev/sda1, а OpenSUSE /dev/hda1 – ну надо ли так морочить людям голову?). Итак, теперь я мог выбрать между Fedora и SUSE в загрузочном меню, хотя несколько нудно, что SUSE при загрузке опять выводит меню Grub и требует выбрать себя в нем. Будь я умнее, я бы скопировал строчку, загружающую SUSE из файла конфигурации Grub с hda1 в файл на hda3, что по идее удобнее, так как можно загружаться прямо в SUSE, минуя второе меню.

Выкрутасы Fedora

Так или иначе, через пару недель я понял, что Fedora мне ни к чему, и решил переразметить ее раздел из SUSE. И вот (загрузившись в SUSE), я запустил:

# mke2fs -j /dev/hda3

для создания новой файловой системы на разделе. Напомню, что hda3 был корневым разделом Fedora. Затем я смонтировал заново созданный раздел в /mnt. Все прошло хорошо, и я перезагрузился. Тут-то и вскрылась язва, потому что в этом месте Grub отказал. Я не мог загрузиться в Fedora – чего и следовало ожидать, раз я удалил ее раздел, но, что более серьезно, SUSE тоже не запускалась. Все, что происходило – появление слова “GRUB” на экране. В этом пункте секрет вашего поведения таков: Без паники! Прокрутите события назад. Снова взгляните на Рис. 3, и вспомните, что содержимое hda3 теперь перезаписано. Загрузчик этапа 1.5, установленный Fedora, ссылается на загрузчик этапа 2 в файловой системе hda3, которого не существует. Все, что нам надо – это переустановить исходные файлы Grub этапов 1 и 1.5 для восстановления возможности загрузки SUSE 10.2.

Единственный способ их вернуть – загрузиться со спасательного диска. Как я уже отметил, для этого годится любой инсталляционный СD Linux, но я выбрал Ubuntu 7.04, поскольку это и Live CD, и ОС Linux, включая рабочий стол Gnome, работающий прямо с CD.

Ubuntu, как и Fedora, называет разделы диска как sda1, sda2, поэтому, как только мой Live CD загрузился, я смог примонтировать корневой раздел SUSE в файловую систему Ubuntu:

$ sudo mount /dev/sda1 /mnt

(Если вы недоумеваете, зачем в этой команде sudo, поясню, что в Ubuntu запрещен прямой вход как суперпользователю, и при каждом запуске команды с привилегиями root требуется использовать sudo. На Live CD пароль для этого не нужен.) Теперь мне нужно запустить Grub и перезаписать MBR. На этом этапе неясно, где находится команда grub (мне нужна копия для SUSE, то есть та, что на hda1), но запустив

$ sudo find /mnt –name grub

я быстро обнаружил, что это /mnt/usr/sbin/grub. Теперь я смог запустить его и ввести команды в командной строке Grub, как показано здесь:

$ sudo /mnt/usr/sbin/grub
grub> root (hd0,0)
grub> setup (hd0) (hd0,0)
 Checking if “/boot/grub/stage1” exists... yes
 Checking if “/boot/grub/stage2” exists... yes
 Checking if “/boot/grub/e2fs_stage1_5” exists... yes
 Running “embed /boot/grub/e2fs_stage1_5 (hd0)”... 15 sectors
are embedded. succeeded
 Running “install /boot/grub/stage1 (hd0) (hd0)1+15 p (hd0,0)/
 boot/Grub/stage2 /boot/grub/menu.lst”... succeeded
Done.
grub> quit

Ключевая команда здесь setup (hd0) (hd0,0), которая велит Grub переустановить оригинальный (SUSE) stage 1 в MBR на (hd0) и скопировать исходный (SUSE) stage 1.5 в сектора, следующие за ним (для более детального описания этого смотрите команды install и embed в руководстве GNU на http://www.gnu.org/software/Grub/manual/Grub.html). Проделав это, я смог просто перезагрузиться и... О-ля-ля! Мое загрузочное меню Grub SUSE вернулось!

Международные спасатели

Live CD вроде Ubuntu или Knoppix прекрасно делают свою работу по спасению загрузки, но кроме них, существуют более маленькие и быстрые диски для восстановления. Некоторые из вас заинтересуются SystemRescueCD (http://www.sysresccd.org) – он не только загружается гораздо быстрее, но также содержит расширенную коллекцию инструментов для управления и редактирования разделов, включая и классику вида gparted, и более экзотические инструменты, вроде NTFS-3g, позволяющий получить доступ к разделам Windows NTFS с полной поддержкой чтения и записи – великолепно для восстановления файлов на старых вышедших из строя разделах Windows XP! Другая вещь, выгодно отличающая этот восстановительный CD – он может кэшировать свою файловую систему в памяти, позволяя вам при необходимости вынуть CD и вставить другой. LXF

Параметры ядра

Частая причина модификации команд Grub – передача загрузочных параметров ядру. Эти параметры просто добавляются в конец строки kernel. Список загрузочных параметров ядра покажет команда man bootparam, или можете купить книгу Грега Кроа-Хартмана [Greg Kroah-Hartmann] «Linux Kernel in a Nutshell» (а где еще найдешь ядро? Прочитайте ее бесплатно на http://www.kroah.com/lkn/), там про это целая глава. Если у вас установлены исходные коды ядра, вы найдете его параметры в /usr/src/linux/Documentation/kernel-parameters.txt. Помните, что многие параметры являются необязательными, и могут или не могут быть настроены в ядре. В таблице они приведены лишь для того, чтобы предоставить вам идею. Запустив Linux, вы можете проверить загрузочные параметры, которые были переданы в него, изучив /proc/cmdline.

КОМАНДЫ ЯДРА

ПАРАМЕТР ДЕЙСТВИЕ
quiet Подавляет ведение журнала ядра, за исключением предупреждений и ошибок. Не используйте его, если вы пытаетесь решить проблему с загрузкой.
splash Выводит заставку и прогресс-индикатор, закрывающие сообщения ядра. Удалив ее, вы можете отследить ошибку.
single or S Велит ядру при запуске init заставлять систему запускаться в одно пользовательском уровне выполнения [run level]. В зависимости от конфигурации у вас спросят или не спросят пароль root; затем вас пустят в оболочку root. X-сервер или графический рабочий стол не стартуют, никакие разделы не монтируются (конечно, за исключением корневого). Это действенный режим для отслеживания проблем X или восстановления файловой системы.
vga=ask Эта опция позволяет вам выбрать режим видеоадаптера. Видеорежим устанавливает разрешение экрана (в виде строк и колонок), и добавив эту опцию, вы сможете быстро выбрать видеорежим из списка. Полезна, если ваш монитор не поддерживает режим по умолчанию.
acpi=off Отключает ACPI (Advanced Configuration and Power Interface ).
init=/bin/sh Запускает программу /bin/sh (оболочку) взамен init. Это даже более экстремально, чем выполнять однопользовательскую загрузку и фактически представляет режим пользователя без инициализации. Загрузка будет исключительно быстрой, и оболочка будет единственным запущенным процессом пользовательского пространства.
Персональные инструменты
купить
подписаться
Яндекс.Метрика