... И всё начинается с рестарта.
Загрузка и инициализация системы

Глава из книги Сага о FreeBSD

Алексей Федорчук

2008-10-29

назад | к началу | вперед

Интерактивное управление процессом загрузки

Возникает вопрос — может ли пользователь повлиять на процесс загрузки? Ответ на него будет положительным. В ходе работы загрузочной системы пользователю трижды предоставляется свобода выбора: выбора загрузочного раздела на начальной стадии boot0, выбора интерактивного управления на стадии boot2 и выбора режима загрузки сразу после запуска loader'а. И во всех этих случаях пользователь может вмешаться в процесс руками. Зачем? Это уже другой вопрос, и ответ на него, надеюсь, станет ясным из последующего изложения.

С выбором раздела загрузки все ясно: он позволяет загрузить одну из ОС, если на данной машине их установлено несколько. А вот на стадии работы boot2 можно прервать его исполнение, точнее — избежать запуска loader'а. Для этого в паузе между выбором загрузки с BSD-раздела и появлением сообщений о загрузке ядра и модулей (пауза эта знаменуется появлением на экране мигающего символа _, и весьма коротка, так что потребуется достаточно быстрая реакция) нужно нажать любую клавишу. В ответ последует приглашение вида:

>> FreeBSD/i386 BOOT
     Default: 0:ad(0,a)/boot/loader
     boot:

В строке приглашения можно указать вариант загрузки, отличный от умолчального. Например, можно загрузить непосредственно файл образа ядра системы. Это может иметь некоторый смысл после пересборки ядра — если новое оказалось сконфигурированным недостаточно корректно для загрузки (но — увы — достаточно, чтобы скомпилироваться).

Для этого нужно сконструировать путь к старому ядру по образу и подобию умолчального варианта. То есть указать:

  • номер диска в машине в соответствие с понимаем BIOS (0 — первый из наличных, 1 — второй, и так далее, вне зависимости от порядка подключения);
  • его интерфейс — в примере ad символизирует ATA диск (для SCSI диска было бы da, для дискеты — fd);
  • номер на IDE-канале (0 — мастер, 1 — слейв);
  • раздел в смысле, используемом BSD Label, то есть часть слайса, резервируемая под корневую файловую систему BSD (a;
  • имя файла образа старого ядра — /kernel.old.

Если на диске имеется несколько первичных разделов разных типов, то разделы не-BSD типа будут пропущены, и литера a (очевидно, что образ ядра может лежать только на корневой файловой системе) будет относиться к первому подразделу слайса с идентификатором 165 (даже если на диске он будет четвертым по счету).

При сомнении в точном имени файла (а их может быть несколько — перед инсталляцией каждого нового неопробованного ядра рекомендуется сделать копию предыдущего, заведомо работоспособного), в строке приглашения можно ввести знак вопроса, ответом на что будет список корневого каталога (но не глубже — просмотреть содержимое подкаталогов, даже в той же файловой системе, на стадии boot2 не удастся).

Впрочем, ту же процедуру — загрузку старого ядра, — можно (и нужно, так как это намного проще) выполнять через loader, к рассмотрению интерактивных возможностей которого мы и переходим.

Меню loader'а предлагает достаточный выбор режимов для штатных ситуаций, но все нештатные (на то они такие и есть) — явно не охватывает. В частности, вариант загрузки старого ядра в меню не предусмотрен. К счастью, предпоследний пункт меню решает эту проблему (и заодно многие другие).

Итак, выбрав пункт шестой меню — Escape to loader prompt, — мы оказываемся в среде командного интерпретатора loader'а. Она имеет шелл-подобный интерфейс — команды с их опциями и аргументами вводятся после приглашения, имеющего вид

OK

С точки зрения удобства интерактивной работы — не GRUB, конечно: ни тебе автодополнения, ни истории команд, возможности редактирования ограничены клавишей Backspace. Но с главной своей ролью — вводом и исполнением встроенных команд, — loader вполне справляется.

Тем более, что команд этих довольно много: полный их список можно получить, введя знак вопроса в командной строке. Доступна и помощь — команда help выдаст краткую подсказку, help имя_команды — более подробные сведения об использовании команды-аргумента. Впрочем, синтаксис команд — также шеллоподобный, так что сложностей с этим быть не должно.

Встроенные команды loader'а можно разделить на три части по их назначению:

  • для получения информации;
  • для конфигурирования загрузчика;
  • собственно для управления процессом загрузки.

Из первой группы команд отметим следующие: ls, lsdev, lsmod, show, more. Первая предназначена для просмотра корневой файловой системы и ее подкаталогов, — правда, только тех, что которые не лежат на отдельных подразделах. Но поскольку все нужные для загрузки файлы лежат в подкаталогах непосредственно корня (в /boot, /dev, /modules), это ограничение не существенно. Вариант команды ls -l выводит список файлов (и каталогов) с указанием их размера — без этой опции только литерой d помечаются каталоги.

Команда lsdev выводит список дисковых устройств, имеющихся в машине, их первичных разделов (слайсов) и логических разделов внутри последних — естественно, только для разделов, размеченных по правилам BSD-разметки). Опция -v обеспечивает детализацию вывода.

Команда lsmod обеспечивает просмотр модулей, загруженных loader'ом до появления меню (или приглашения командной строки). Как и в предыдущем случае, имеется опция детализации — -v.

Команда show выполняет аналогичную функцию, но в отношении переменных загрузчика. Данная без аргумента, она выводит значения для всех определенных переменных. Если же в качестве аргумента указать имя переменной, то будет показано только ее значение. Допустимо несколько аргументов, разделяемых точкой с запятой.

Ну а more выполняет те же функции, что и ее тезка из числа Unix-утилит. Она позволяет просмотреть содержимое текстового файла — то есть, находясь в командном интерпретаторе loader'а, мы можем ознакомиться с конфигами, важными для загрузки (и с любыми другими).

Команды конфигурирования позволяют определить или снять переменные загрузчика, загрузить или удалить модули ядра. Как уже говорилось, само ядро с неким предопределенным набором модулей и переменных загружается до меню loader'а и его командного интерпретатора. Так вот, с помощью соответствующих команд эти предопределенные наборы можно несколько скорректировать (или изменить полностью). Это может быть необходимо, если умолчальная конфигурация ядра по каким-либо причинам не грузится (частый случай — конфликт ноутбучных систем энергосбережения с системными модулями ACPI), в отладочных целях, или просто удовлетворения любопытства для.

Сначала рассмотрим команды управления модулями. Это — пара команд load и unload для загрузки и удаления модулей, соответственно. Первая используется с аргументом имя_модуля, каковое при необходимости можно подсмотреть (с помощью ls) в каталоге /modules — имя в аргументе дается без суффикса *.ko. Команда unload с аналогичным аргументом удалит указанный модуль, без аргументов — удалит все модули вообще, позволяя начать конфигурирование с чистого листа.

Действие команд load и unload распространяется также на ядро в целом. Так, посредством команды

OK unload kernel

можно выгрузить из памяти умолчальное ядро (например, если оно оказалось неработоспособным), а с помощью команды

OK load kernel.old

загрузить ядро старое, трудоспособное.

Пара команд аналогичного назначения — set и unset, — существует и для управления переменными окружения загрузчика. Переменные эти служат для изменения текущего дискового устройства, указания расположения корневой файловой системы, определения путей к модулям ядра, отличным от умолчального /modules, и тому подобных вещей. Делается это командой set в соответствие с синтаксисом C-shell, например:

OK set currdev="disk1s1a"

Определяет текущее дисковое устройство в терминах "диск#_слайс#_раздел".

Допустимо несколько значений для одной переменной — они разделяются точкой с запятой. Например, команда

OK set module_path="/boot;/boot/modules;/path2mymodule"

определяет расположение модулей ядра — корневой, умолчальный каталог modules и каталог /path2mymodule: очевидно, что если просто определить в этой переменной путь к собственным модулям, информация о расположении модулей умолчальных была бы утрачена.

Некоторые переменные просто разрешают или запрещают какие-то действия, и, соответственно, значения их булевы — YES или NO. Естественно, они нуждаются в детализирующих переменных, определяющих то, что ими было разрешено. Например, переменная

OK set userconfig_script_load="YES"

только разрешает исполнение пользовательских сценариев конфигурирования, а переменная

OK set userconfig_script_name="/boot/my.conf"

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

С помощью переменных можно определять и режимы загрузки. Например, после установки переменной

OK set boot_single

загрузка будет осуществляться в однопользовательском режиме.

Определение переменной может отменяться командой

unset имя_переменной

В некоторых случаях ее эквивалентом будет определение переменной с булевым значением NO или словом disable в имени.

Полный список встроенных переменных окружения загрузчика можно посмотреть на соответствующей man-странице:

$ man 8 loader

И, наконец, команды управления загрузкой. Важнейшая из них — boot, без опций и аргументов вызывающая немедленную загрузку ядра в его умолчальной или текущей (то есть с переопределенными переменными и модулями) конфигурации. /p>

Опции команды boot конкретизируют режим загрузки. Например, команда

OK boot -s

вызовет загрузку в однопользовательском режиме. Это эквивалентно тому, как если бы выполнить ту же команду без опций, предварительно установив переменную boot_single.

Аргументы команды boot могут определять имя образа ядра, исполняемого сценария загрузки, и так далее. Тот же сакраментальный пример: команда

OK boot kernel.old

приведет к загрузке старого ядра, аналогично команде boot без опций после исполнения пары

OK unload kernel
OK load kernel.old

Впрочем, первая команда этой пары все равно не помешает — во избежание... Особенно если новое ядро собралось уж совсем криво.

Здесь было рассказано не о всех возможностях интерактивного режима BSD-загрузчика — только о тех, которые мне довелось применять. Более подробные сведения можно почерпнуть не только в man (8) loader, но и непосредственно чтением файла помощи:

$ less /boot/loader.help

И совсем не обязательно в процессе управления загрузкой — лучше сделать это заблаговременно.

назад | к началу | вперед