Глава из книги Сага о FreeBSD
Алексей Федорчук
2008-10-29
Возникает вопрос — может ли пользователь повлиять на процесс загрузки? Ответ на него будет положительным. В ходе работы загрузочной системы пользователю трижды предоставляется свобода выбора: выбора загрузочного раздела на начальной стадии boot0, выбора интерактивного управления на стадии boot2 и выбора режима загрузки сразу после запуска loader'а. И во всех этих случаях пользователь может вмешаться в процесс руками. Зачем? Это уже другой вопрос, и ответ на него, надеюсь, станет ясным из последующего изложения.
С выбором раздела загрузки все ясно: он позволяет загрузить одну из ОС, если на данной машине их установлено несколько. А вот на стадии работы boot2 можно прервать его исполнение, точнее — избежать запуска loader'а. Для этого в паузе между выбором загрузки с BSD-раздела и появлением сообщений о загрузке ядра и модулей (пауза эта знаменуется появлением на экране мигающего символа _, и весьма коротка, так что потребуется достаточно быстрая реакция) нужно нажать любую клавишу. В ответ последует приглашение вида:
>> FreeBSD/i386 BOOT
Default: 0:ad(0,a)/boot/loader
boot:
В строке приглашения можно указать вариант загрузки, отличный от умолчального. Например, можно загрузить непосредственно файл образа ядра системы. Это может иметь некоторый смысл после пересборки ядра — если новое оказалось сконфигурированным недостаточно корректно для загрузки (но — увы — достаточно, чтобы скомпилироваться).
Для этого нужно сконструировать путь к старому ядру по образу и подобию умолчального варианта. То есть указать:
0 — первый из наличных, 1 — второй, и так далее, вне зависимости от порядка подключения);ad символизирует ATA диск (для SCSI диска было бы da, для дискеты — fd);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
И совсем не обязательно в процессе управления загрузкой — лучше сделать это заблаговременно.