Введение в POSIX'ивизм

Особенности загрузчиков Lilo и GRUB


К тому же BSD Loader - далеко не самый распространенный из мультисистемных загрузчиков в свободном POSIX-мире. Многие пользователи Linux применяют в этом качестве Lilo (Linux Loader). Те же, кто по долгу или прихоти использует множество (более двух) операционных систем, да еще и меняют их, как перчатки, обычно отдают предпочтение загрузчику GRUB ( GRand Unified Bootloader).

Загрузчик Lilo и его настройка - предмет подробного описания в любой толстой книге про Linux. Поэтому скажу про него лишь пару строк. Это - такой же "цепочечный" загрузчик, как и BSD Loader. То есть в общем случае он записывается в MBR загрузочного диска, откуда при старте машины опознает дисковые разделы - как первичные, так и расширенные. И если раздел несет на себе метку Linux native - загрузит с него образ ядра Linux (изначально Lilo для этого и предназначался, его функции мультисистемного загрузчика вторичны). Если же тип раздела - иной, Lilo в состоянии "по цепочке" передать управление на его загрузочный сектор, и дальнейшее будет определяться тем кодом, что записан в последнем.

Тип файловой системы для Lilo по большому счету безразличен - то есть он способен загрузить ядро Linux с любой из ее многочисленных нативных файловых систем. Однако до недавнего времени он не мог выполнить эту операцию с файловой системы ReiserFS в случае, если в ней использовался так называемый tailing (или упаковка хвостов - см. ). Хотя ныне это, как-будто бы изжито, при размещении ReiserFS на корневом разделе обычно все равно рекомендуется выделять специальный раздел /boot с файловой системой Ext2fs - под ядро и служебные его файлы, для страховки. Ведь, хотя использование тайлинга можно отключить, он автоматически восстанавливается при реинсталляции ядра на файловой системе, несущей оное.

Для разделов "чуждых" операционок тип их файловой системы для Lilo безразличен тем более - ведь, как уже было сказано, он просто передает управление на их загрузочные сектора. И поэтому, если озаботиться тем, чтобы в загрузочном секторе BSD-слайса был записан код boot1 из BSD Loader, то Lilo благополучно справится с загрузкой любой ОС этого семейства.
А возможность записи соответствующего кода при установке BSD-систем предоставляется. Точно таким же способом - по "цепочке" - Lilo может обеспечить загрузку DOS, Windows 3.X/9X/ME и Windows NT/2000/XP.

Каждая ОС, предусмотренная для "загрузки" через Lilo (вы ведь понимаете, почему теперь я взял это слово в кавычки? - именно, потому что в полном смысле слова оно применимо только к загрузке Linux), представляет собой один из вариантов выбора в меню этой программы. Важно, что таким вариантом не обязательно отдельная операционка, - это могут быть разные дистрибутивы Linux, лежащие на собственных разделах, и разные версии ядра одной и той же Linux-системы, и просто разные сборки ядра одной и той же версии. Поэтому Lilo очень часто применяют для тестирования ядер этой системы, скомпилированных с разными опциями, или ядер разрабатываемой ветки.

Варианты загрузки через Lilo описываются в его специальном конфигурационном файле - /etc/lilo.conf. Это простой текстовый файл, доступный для изменения в текстовом редакторе (при наличии полномочий суперпользователя, разумеется). Он содержит несколько секций - общую, описывающую условия загрузки в целом и отдельные - описание каждого варианта загрузки.

Общая секция в виде отдельных строк содержит:

  • имя устройства, с которого выполняется запуск Lilo (именно Lilo, а не Linux или иной ОС), для случая первого диска это будет как boot=/dev/hda;


  • время ожидания выбора вариантов загрузки - timeout=##, где ## - время в миллисекундах;


  • имя варианта, загружаемого по умолчанию, которое должно соответствовать тому, что далее будет указано в секции этого варианта;


  • указание на режим - нынче это, как правило, строка вида lba32.




  • Содержание отдельных секций различается в зависимости от того, предназначен этот вариант для загрузки Linux или иной ОС. В общем случае обязательными здесь будут две строки. Первая - это метка варианта (label) - его уникальный идентификатор в виде произвольной, но, желательно, мнемонически прозрачной последовательности символов, например: linux, freebsd, windows.


    Вторая же - имя устройства, несущего загружаемую ОС или его корневую систему (вроде /dev/hda1, /dev/hda5, и так далее).

    Секция варианта, загружающего Linux, кроме обязательного идентификатора, должна включать:

  • имя файла, содержащего образ ядра, с указанием пути относительно корневого каталога, заданного в одной из следующих строк, что обычно выглядит как image=/boot/bzImage или image=/boot/vmlinuz;


  • имя устройства, несущего корневую файловую систему, для случая первого раздела на первом диске это будет root=/dev/discs/disc0/part1 при использовании файловой системы устройств или /dev/hda1 - без оной (или при использовании udev - см. Интермедию 12);


  • указание монтировать корневую файловую систему при загрузке ядра в режиме "только для чтения" read-only; это не значит, что она станет недоступной для изменений - в процессе инициализации файловые системы будут перемонтированы в соответствие с их описанием в /etc/fstab.


  • Кроме того, в Linux-секции /etc/lilo.conf вносятся строки, определяющие видеорежим при загрузке (например, vga=791 - режим графической консоли с разрешением 1024x768) и строки, передающие ядру некоторые параметры, вроде append="devfs=nomount" (запрет на монтирование файловой системы устройств, требующийся при задействовании механизма udev), или append="ide-scsi" (включение эмуляции протокола SCSI через IDE-шину).

    Секции для не-Linux вариантов, как правило, не содержат ничего, кроме имени устройства несущего раздела и метки варианта:

    other=/dev/discs/disc0/part1 label=dos

    Lilo может использоваться и исключительно для загрузки единичной Linux-системы в сочетании с любым мультисистемным загрузчиком, отвечающим за загрузку систем прочих (BSD Loader, GRUB, вплоть до NT Loader). В этом случае в общей секции /etc/lilo.conf в качестве загрузочного устройства следует указать имя корневого раздела Linux-системы - ведь тогда Lilo будет стартовать уже с его загрузочного сектора (а не с MBR диска):

    boot=/dev/hda1

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


    А далее возможны и отдельные секции для вариантов загрузки, но они будут описывать уже не самостоятельные ОС, а разные версии или сборки ядра, возможно - видеорежимы или параметры ядра.

    Как уже было сказано, Lilo напрямую с файловыми системами не работает - даже файловыми системами Linux. Конфиг же этого загрузчика лежит в каталоге /etc, представляющем собой часть файлового древа инсталлированной Linux-системы, которая при старте машины еще не загружена. Как же загрузчик узнает о собственной конфигурации?

    Очень просто, о существовании собственного конфига в момент запуска Lilo и не подозревает. Необходимые данные для его опознания прошиты в виде бинарного кода в загрузочном секторе - диска или раздела. И делается это одноименной командой - /sbin/lilo. При запуске она обращается к файлу /etc/lilo.conf, исходя из значения строки

    boot=/dev/имя_устройства

    в общей его секции, определяет, куда нужно записать данные - в MBR диска или загрузочный сектор раздела, и выполняет запись вариантов загрузки, завершаемую сообщением

    Added имя_рек

    где имя_рек - метка (label) добавленного или модифицированного пункта меню.

    Из чего становится очевидным, что каждое изменение конфигурации загрузчика должно сопровождаться его переустановкой - перезапуском программы /sbin/lilo.

    Сказанным в предыдущих абзацах определяются и два принципиальных ограничения на использование Lilo вообще. Первое вытекает из положения конфига этого загрузчика внутри файловой системы Linux. Так что для изменения его конфигурации из другой операционной системы необходимо иметь доступ к той файловой системе, на которой лежит корень инсталлированного Linux'а, причем в режиме записи. И если примонтировать Ext2fs/Ext3fs к файловой системе FreeBSD или DragonFlyBSD в режиме read/write можно без проблем (ныне это не потребует даже пересборки ядра и той, и другой ОС), то доступ из любой ОС BSD-семейства к разделам с ReiserFS или XFS в настоящее время невозможен (и неизвестно, будет ли возможен в обозримом будущем).

    Конечно, можно взять за правило размещать корневую систему Linux только на разделе с Ext2fs/Ext3fs.


    Однако второе ограничение - необходимость перезапуска /sbin/lilo, - этим не обходится, ведь эта программа предназначена для работы в родной ОС, сиречь Linux (интересно, а пробовал ли кто-нибудь запустить /sbin/lilo под FreeBSD в режиме Linux Compability?). И, соответственно, непременное условие для переконфигурирования Lilo - возможность запуска Linux в каком-никаком виде, хотя бы - с rescue-дискеты или LiveCD.

    Есть и третье ограничение, не столь важное: относительно слабые (по сравнению с GRUB) интерактивные возможности. Конечно, Lilo позволяет в режиме командной строки вмешиваться руками в ход загрузки - но только загрузки Linux же (например, передавать параметры ядру). Да и то - в ограниченном объеме. Возможности же вмешательства в ход загрузки чужой ОС вообще заканчиваются в момент выбора соответствующего ей варианта.

    Раз уж речь зашла об ограничениях Lilo, то, пользуясь случаем, подчеркну: прочие ограничения, на которые можно нат олкнуться в литературе, как то: невозможность загрузить ядро Linux с области диска, лежащей за пределами первых 1024 его цилиндров, или с логического раздела в разделе Extended DOS, - давно потеряли силу. И пользователь любого современного дистрибутива о них может смело забыть.

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

    Как и Lilo, GRUB неоднократно был предметом описания в различных (преимущественно онлайновых) документах. Наиболее полное (из числа мне известных) содержится в цикле статей Владимира Попова, который можно найти здесь: http://unix.ginras.ru/linux/base011.html. К которой я отсылаю любознательного читателя, затронув ниже лишь основные особенности и возможности этой программы.

    Если Lilo, как и следует из его названия, создавался в первую очередь для загрузки Linux при сохранении возможности старта Windows, то целью разработчиков GRUB изначально было создание универсального мультизагрузчика, максимально независимого от любой операционной системы.


    История его началась в 1995 году, когда операционная система GNU Hurd (микроядерная ОС светлого будущего, столь же отдаленного, как и коммунизм в мировом масштабе) достигла той степени развития, что могла уже быть загружена. И встал вопрос - каким же образом это сделать, так как существовавшие тогда загрузчики оказались на это неспособными.

    Конечно, с точки зрения идеологии GNU, логично было бы изобрести для этой цели собственный (еще один) загрузчик, в полной мере отвечающий идеалам свободы и демократии. Однако, к счастью для всего прогрессивного человечества, был избран иной путь: Multiboot Specification - универсальный метод загрузки ядер, этой самой спецификации соответствующих. Причем сама спецификация бралась отнюдь не с потолка - в ее основу легли особенности существующих ядер Linux и BSD-систем. Ведь, как я уже говорил, файлы их образов самодостаточны для запуска и несут в себе всю необходимую информацию - и дело упирается только в то, что в обычной ситуации они расположены на носителе с файловой системой, поддержка которых начинается только после загрузки соответствующего ядра. Так что суть универсальности предложенного метода и заключалась в том, чтобы загрузчик получил средства доступа к файловой системе.

    Зримым же, действительно универсальным, воплощением Multiboot Specification и стал мультисистемный загрузчик GRUB. Собственно, единственным его ограничением для полноценного использования (ниже станет ясно, что "неполноценное" использование GRUB вообще ничем не ограничено) была совместимость с файловой системой загружаемой ОС. Ибо, в отличие от BSD Loader и Lilo, GRUB способен работать с очень многими файловыми системами напрямую, без всякого использования ресурсов соответствующей операционки - "монтировать", читать с них данные, подвергать их редактированию и записывать изменения. Что превращает его в своеобразную мини-ОС, имеющую к тому же свой собственный, шелл-подобный, интерфейс пользователя.

    Можно выделить две степени совместимости GRUB с файловыми системами - полную и частичную.


    Полностью совместимые файловые системы - это те, что способны нести GRUB сам по себе. И в их числе - абсолютно все нативные файловые системы Linux (включая JFS, имевшие некогда место проблемы с "монтированием" ReiserFS, насколько я знаю, в прошлом), Minix и FAT. То есть загрузчик GRUB может стартовать с любого носителя, отформатированного соответствующим образом - дискового раздела, дискеты Linux (на которых применяется файловая система Minix) или DOS (с файловой системой FAT). Хотя по причинам, которые скоро станут понятны, разработчики рекомендуют размещать GRUB на самостоятельном разделе с файловой системой Ext2fs.

    Частично совместимые с GRUB файловые системы сами по себе нести его не могут. Но после своего старта он способен их идентифицировать, прочитать и загрузить с них ядро, если оно отвечает Multiboot Specification. И в эту группу попадают практически все файловые системы свободных операционок, внутренний формат которых общедоступен - кроме Linux, тут мы видим также все варианты FFS и UFS, используемых BSD-семейством. Если же какая-то из таких файловых систем (как правило, из числа только что созданных) кажется несовместимой с текущей версией GRUB - это исключительно временное явление. Потому что для любой открытой файловой системы нет никаких препятствий получить свою поддержку в GRUB.

    Приведу пример: с появлением 5-й ветки FreeBSD она обрела новую нативную файловую систему, UFS2, несколько отличную от прототипа - UFS просто. В результате единовременная версия GRUB (0.93) оказалась неспособной работать с ней напрямую (ниже я покажу, что это все равно было обходимо). Однако уже для версии 0.94 появился патч поддержка UFS2, а с версии 0.95 GRUB поддерживает эту файловую систему, что называется, "из тарбалла".

    Можно видеть, что в списке частично совместимых с GRUB файловых систем нет тех, что созданы Самой Великой Софтверной компанией, в частности - всех вариантов NTFS. Что понятно - ведь их внутреннее устройство - тайна за семью печатями.


    Однако мир свободного софта в очередной раз подтверждает справедливость утверждения, что на самое хитрое ухо (вариант для дам) всегда найдется болт с левой резьбой. Существует он и здесь: операционки, файловые системы которых для GRUB недоступны, могут быть загружены "по цепочке" - передачей управления на загрузочный сектор соответствующего раздела. Тот же способ можно применить и для загрузки свободных ОС, файловые системы которых временно не поддерживаются на моей памяти таковыми бывали периодически некоторые версии OpenBSD и FreeBSD 5-й ветви. К слову сказать - даже "ухо с закоулками" (несовместимость ядра с Multiboot Specification, имеющая место для DOS/Windows9X/ME) не оказывается помехой для винта от GRUB. И указанные операционки могут быть столь же успешно загружены "цепочечным" методом.

    Таким образом, универсализм GRUB в рабочем (то есть установленном и настроенном) состоянии сомнений не вызывает. Однако с точки зрения установки и настройки он предстает столь же независимым от любой ОС. Ибо устанавливается он с самодостаточной загрузочной дискеты. А с недавнего времени, благодаря усилиям Владимира Попова, это можно проделать и с мультизагрузочного LiveCD (который можно скачать отсюда). То есть: наличия инсталляции какой-либо ОС (или дистрибутива Linux не требуется).

    Что же касается конфигурирования GRUB, то, если следовать приведенным ранее рекомендациям разработчиков (установке GRUB на отдельный дисковый раздел с файловой системой Ext2fs - и резоны к тому сейчас прояснятся), то и тут никаких сложностей не предвидится ни в одной из свободных ОС. В Linux этот раздел монтируется как каталог /boot, куда, вместе с файлами собственно загрузчика (в подкаталоге /boot/grub) помещаются также файлы ядра (/boot/vmlinuz и подобные ему). Причем разработчики опять же рекомендуют монтировать /boot не автоматически при старте Linux - после ее загрузки никакой необходимости к этому каталогу в обычных условиях нет), а руками - по мере необходимости (установки нового ядра или реконфигурации GRUB).



    За настройку загрузки GRUB отвечает специальный файл, доступный из Linux как /boot/grub/menu.lst. Это простой текстовый файл, который можно модифицировать в любом редакторе. Причем, что ценно, предварительно проверив работоспособность вносимых изменений в интерактивном режиме. Описывать его формат в деталях не буду, он очень прост и станет ясным и приводимого в заключении примера.

    Так что для конфигурирования же GRUB из какой-либо иной ОС требуется только возможность чтения раздела с Ext2fs и записи в него. А, как уже говорилось, получить такую возможность из FreeBSD и DragonFlyBSD ныне никакого труда не составит (да и в случае Net- или OpenBSD в худшем случае потребуется только пересборка их ядер). Так что рекомендация разработчиков о выборе файловой системы загрузочного раздела становится понятной - прочие файловые системы Linux BSD-семейством не поддерживаются, а FAT... ну он FAT и есть, всерьез говорить о нем не стоит.

    Таковы основные особенности (и возможности) GRUB. О деталях его установки, настройки и интерактивной работы в ходе загрузки можно было бы написать еще много. Однако это уже проделано Владимиром Поповым, и повторяться я не буду. Памятуя и о прекрасной штатной документации этой программы, правда, в нелюбимом мною формате (info grub, стандартный man grub содержит лишь краткие о ней сведения). Так что в качестве завершающего штриха просто приведу прокомментированный (строки комментариев, как обычно, отмечены символом #) пример своего конфига, который долгое время верой и правдой служил мне при загрузке Archlinux.

    # Config file for GRUB - The GNU GRand Unified Bootloader # /boot/grub/menu.lst

    # Общая конфигурация загрузчика timeout 5 # Время ожидания выбора загружаемой ОС в секундах default 0 # ОС, загружаемая по умолчанию # (в данном случае Linux) color light-blue/black light-cyan/blue # Цветовая гамма меню (мне такая нравится)

    # Секция, отвечающая за загрузку Archlinux # (0) Arch Linux title Arch Linux [/boot/vmlinuz] # Идентификатор ОС # он же - пункт меню загрузчика root (hd0,1) # Устройство, несущее корневую файловую систему: # 2-й раздел 1-го диска в нотации GRUB # В нотации Linux ему соответствует устройство # /dev/discs/disc0/part2 в следующей строке kernel (hd0,0)/vmlinuz root=/dev/discs/disc0/part2 ro # где # (hd0,0)/vmlinuz - положение файла образа ядра # на загрузочном устройстве в нотации GRUB - # 1-м разделе 1-го диска # root=/dev/discs/disc0/part2 # имя устройства с корневой файловой системой # уже в нотации Linux (при использовании devfs) # ro - предписание монтировать его в режиме read-only

    А в ближайшей же интермедии я остановлюсь на вопросе, недостаточно освещенном в источниках - загрузке с помощью GRUB систем BSD-клана (в том числе и при отсутствии доступа к их файловой системе).


    Содержание раздела