Введение в ос linux

Вид материалаДокументы

Содержание


Загрузчик ядра
Досистемная загрузка Linux
Подобный материал:
1   ...   31   32   33   34   35   36   37   38   ...   62

Загрузчик ядра


В задачу вторичного загрузчика входит загрузка и начальная настройка ядра операционной системы. Как правило, ядро системы записывается в файл с определённым именем. Но как вторичному загрузчику прочитать файл с ядром, если в Linux эта операция и есть функция ядра? Эта задача может быть решена тремя способами.

Во-первых, ядро может и не быть файлом на диске. Если загрузка происходит по сети, достаточно попросить у сервера "файл с таким-то именем", и в ответ придёт цельная последовательность данных, содержащая запрошенное ядро. Все файловые операции выполнит сервер, на котором система уже загружена и работает. В других случаях ядро "загоняют" в специально выделенный под это раздел, где оно лежит уже не в виде файла, а таким же непрерывным куском, размер и местоположение которого известны. Однако в Linux так поступать не принято, так как места для специального раздела на диске, скажем, IBM-совместимого компьютера, может и не найтись.

Во-вторых, можно воспользоваться описанной выше картой размещения: представить ядро в виде набора секторов на диске, записать этот набор в заранее определённое место, а загрузчик заставить собирать ядро из кусков по карте. Использование карты размещения имеет два существенных недостатка: её создание возможно только под управлением уже загруженной системы, а изменение ядра должно обязательно сопровождаться изменением карты. Если по какой-то причине система не загружается ни в одной из заранее спланированных конфигураций, единственная возможность поправить дело -- загрузиться с внешнего носителя (например, с лазерного диска). А система может не загружаться именно потому, что администратор забыл после изменения ядра пересобрать карту: в карте указан список секторов, соответствовавших старому файлу с ядром, и после удаления старого файла в этих секторах может содержаться какой угодно мусор.

В-третьих, можно научить вторичный загрузчик распознавать структуру файловых систем, и находить там файлы по имени. Это заметно увеличит его размер и потребует "удвоения функций", ведь точно такое же, даже более мощное, распознавание будет и в самом ядре. Зато описанной выше тупиковой ситуации можно избежать, если, скажем, не удалять старое ядро при установке нового, а переименовывать его. Тогда, если загрузка системы с новым ядром не удалась, можно загрузиться ещё раз, вручную указав имя файла (или каталога) со старым ядром, под чьим управлением всё работало исправно.

Вторичный загрузчик может не только загружать ядро, но и настраивать его. Чаще всего используется механизм настройки ядра, похожий на командную строку shell: в роли команды выступает ядро, а в роли параметров -- настройки ядра. Настройки ядра нужны для временного изменения его функциональности: например, чтобы выбрать другой графический режим виртуальных консолей, чтобы отключить поддержку дополнительных возможностей внешних устройств (если аппаратура их не поддерживает), чтобы передать самому ядру указания, как загружать систему и т. п.

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

Особенная ситуация возникает в случае, когда на компьютере установлено несколько операционных систем (например, если персональный компьютер используется также и для компьютерных игр, строго привязанных к определённой системе). В этом случае не стоит надеяться на "универсальность" вторичного загрузчика: даже если он способен различать множество файловых систем и несколько форматов загрузки ядер, невозможно знать их все. Однако, если в загрузочном секторе раздела операционной системы записан первичный загрузчик, можно просто загрузить его, как если бы это произошло непосредственно после работы MBR. Таким образом, вторичный загрузчик может выступать в роли предзагрузчика, передавая управление "по цепочке" (chainloading). К сожалению, чем длиннее цепочка, тем выше вероятность её порвать: можно, например, загрузить по цепочке MS-DOS, удалить с его помощью раздел Linux, содержавший вторичный загрузчик, переразметить этот раздел, чем и привести компьютер в неработоспособное состояние.

вторичный загрузчик

Вторая стадия загрузки компьютера: программа, размер и возможности которой практически не зависят от аппаратных требований. Основная задача -- полностью подготовить и запустить загрузку операционной системы.

Досистемная загрузка Linux


Несмотря на то, что досистемная загрузка не зависит от типа операционной системы, которая начинает работу после неё, большинство систем предоставляют собственные средства по её организации. В Linux наиболее популярны подсистемы загрузки LILO (LInux LOader) и GRUB (GRand Unified Bootloader). Обе эти подсистемы имеют текстовый и графический варианты интерфейса, предоставляющего пользователю возможность выбрать определённый заранее настроенный тип загрузки.

LILO


Подсистема загрузки LILO использует и для первичного, и для вторичного загрузчика схему с картой размещения. Это делает работу с LILO занятием, требующем повышенной аккуратности, так как изменение процедуры загрузки не атомарно: сначала пользователь изменяет ядро или его модули, потом -- редактирует файл /etc/lilo.conf, в котором содержатся сведения обо всех вариантах загрузки компьютера, а затем -- запускает команду lilo, которая собирает таблицы размещения для всех указанных ядер и вторичного загрузчика и записывает первичный и вторичный загрузчик вместе с картами в указанное место диска. Первичный загрузчик LILO (он называется LI) можно записывать и в MBR, и в начало раздела Linux.

Простейший файл lilo.conf может выглядеть так:

boot=/dev/hda

map=/boot/map

image=/boot/vmlinuz-up

root=/dev/hda1

Простейшая настройка LILO: пример файла lilo.conf

Такая настройка LILO определяет ровно один вариант загрузки: первичный загрузчик записывается в начало первого жёсткого диска (строчка boot=/dev/hda), карту размещения утилита lilo записывает в файл /boot/map, ядро добывается из файла /boot/vmlinuz-up, а запись root=/dev/hda1 указывает ядру, что корневая файловая система находится на первом разделе первого диска.

Одна из машин, за которыми случалось работать Мефодию, использовалась иногда для запуска единственной программы, написанной для MS-DOS. Исходные тексты этой программы давно потерялись, автор -- тоже, поэтому на машине пришлось устанавливать и MS-DOS и Linux. В результате lilo.conf оказался таким:

[root@localhost root]# cat /etc/lilo.conf

boot=/dev/hda

map=/boot/map

default=linux-up

prompt

timeout=50

image=/boot/vmlinuz-up

label=linux-up

root=/dev/hda5

initrd=/boot/initrd-up.img

read-only

image=/boot/vmlinuz-up

label=failsafe

root=/dev/hda5

initrd=/boot/initrd-up.img

vga=normal

append=" failsafe noapic nolapic acpi=off"

read-only

other=/dev/hda1

label=dos

other=/dev/fd0

label=floppy

unsafe

Настройка LILO на двухсистемной машине

Здесь Linux был установлен на пятый раздел диска (о нумерации разделов в IBM-совместимых компьютерах рассказано в лекции ссылка скрыта), а на первом находится MS-DOS. Кроме загрузки MS-DOS предусмотрено два варианта загрузки Linux и ещё один -- любой операционной системы с дискеты. Каждый вариант загрузки помечен строкой label=вариант. При старте LILO выводит простейшее(3) окошко, в котором перечислены все метки (в данном случае -- "linux-up", "failsafe", "dos" и "floppy"). Пользователь с помощью "стрелочек" выбирает нужный ему вариант и нажимает Enter. При необходимости пользователь может вручную дописать несколько параметров, они передадутся ядру системы. Если пользователь ничего не трогает, по истечении тайм-аута выбирается метка, указанная в поле default.

Ещё несколько пояснений. Метки linux-up и failsafe в примере используют одно и то же ядро (vmlinuz-up), но во втором случае перенастраивается режим графической карты и добавляются параметры, отключающие поддержку необязательных для загрузки аппаратных расширений (многопроцессорность, автоматическое управление электропитанием и т. п.). Строчку, стоящую после append= пользователь мог бы ввести и самостоятельно, это и есть параметры ядра. Поле initrd= указывает, в каком файле находится стартовый виртуальный диск (ему посвящён раздел Стартовый виртуальный диск и модули ядра этой лекции), а внушающая некоторые опасения надпись "unsafe" (для метки floppy) означает всего лишь, что дискета -- съёмное устройство, поэтому бессмысленно во время запуска lilo проверять правильность её загрузочного сектора и составлять карту.

Наконец, записи вида other=устройство говорят о том, что LILO неизвестен тип операционной системы, находящейся на этом устройстве, а значит, загрузить ядро невозможно. Зато ожидается, что в первом секторе устройства будет обнаружен ещё один первичный загрузчик, LILO загрузит его и передаст управление по цепочке. Так и загружается MS-DOS на этой машине: первичный загрузчик берётся (по метке dos) из начала первого раздела первого диска.

GRUB


Подсистема загрузки GRUB устроена более сложно. Она также имеет первичный загрузчик, который записывается в первый сектор диска или раздела, и вторичный загрузчик, располагаемый в файловой системе. Однако карта размещения в GRUB обычно используется только для т. н. "полуторного" загрузчика ("stage 1.5") -- по сути дела, драйвера одной определённой файловой системы. Процедура загрузки при этом выглядит так. Первичный загрузчик загружает полуторный по записанной в него карте размещения. Эта карта может быть очень простой, так как обычно полуторный загрузчик размещается непосредственно после первичного подряд в нескольких секторах(4), или в ином специально отведённом месте вне файловой системы. Полуторный загрузчик умеет распознавать одну файловую систему и находить там вторичный уже по имени (обычно /boot/grub/stage2). Наконец, вторичный загрузчик, пользуясь возможностями полуторного, читает из файла /boot/grub/menu.lst меню, в котором пользователь может выбирать варианты загрузки так же, как и в LILO. Таким образом, обновление и перенастройка установленного GRUB не требует пересчёта карт размещения и изменения чего-то, кроме файлов в каталоге /boot/grub.

По требованию Мефодия, Гуревич установил на двухсистемную машину GRUB. При этом файл /boot/grub/menu.lst получился таким:

[root@localhost root]# cat /boot/grub/menu.lst

default 0

timeout 50


title linux-up

kernel (hd0,4)/boot/vmlinuz-up root=/dev/hda5

initrd (hd0,4)/boot/initrd-up.img


title failsafe

kernel (hd0,4)/boot/vmlinuz-up root=/dev/hda5 failsafe noapic nolapic acpi=off

initrd (hd0,4)/boot/initrd-up.img


title floppy

root (fd0)

chainloader +1


title dos

root (hd0,0)

chainloader +1

Настройка GRUB на двухсистемной машине

Разница между lilo.conf только в синтаксисе, да ещё в том, что жёсткие диски и разделы на них GRUB именует по-своему, в виде (hdномер_диска,номер_раздела), причём нумеровать начинает с нуля. Метки ("title") тоже нумеруются с нуля, так что запись default 0 означает, что по истечении тайм-аута будет загружена самая первая конфигурация (по имени "linux-up").

Изучая руководство по GRUB, Мефодий обнаружил гораздо более важное отличие от LILO. Оказывается, в GRUB не только параметры, но и сами файлы (ядро, стартовый виртуальный диск и т. п.) распознаются и загружаются в процессе работы. Вместо пунктов меню можно выбрать режим командной строки, подозрительно похожий на bash, в котором заставить GRUB загрузить какое-нибудь другое, не предписанное конфигурацией, ядро, посмотреть содержимое каталогов файловой системы, распознаваемой полуторным загрузчиком, и даже содержимое этих файлов, невзирая ни на какие права доступа: система-то ещё не загружена. Мало того, можно по-своему перенастроить загрузчик и записать результаты настройки. Так и не успев сполна насладиться неожиданной свободой, Мефодий в один прекрасный день обнаружил, что выход в командную строку защищён паролем.