unix 2010-06-01 14-41-04
GRUB - GRand мира загрузчиков
Владимир Попов
4 Октябрь 2005 г
От редактора: на протяжении последних лет Владимир написал несколько отдельных заметок на тему заглавия, освещающих разные ее аспекты и ничуть не утративших своей актуальности. Я взял на себя смелость (с разрешения автора) свести их воедино, результаты чего и предлагаю вниманию читателей. Итоговый текст естественным образом распадается на три, частично пересекающиеся, части - Введение для всех, Введение для подоконников и Расширение для POSIX'ивистов. - Алексей Федорчук.
Введение в предмет
"Существование" любой вычислительной системы представляет собой процесс последовательного выполнения главным вычислительным узлом (в миру - CPU) инструкций (операторов). И, как процесс "последовательный", он должен как-то начинаться. Со времен первых ЭВМ для определения этого начала используют специальное слово "boot", общепринятый русский перевод которого - "начальная загрузка", "загрузить". Спросите, зачем так "издалека"? А затем, что большинство пользователей никогда не задумывалось над тем, что представляют собой эти самые boot loader-ы (первичные загрузчики).
Общепринятым заблуждением является то, что загрузчик - часть ОС, что, в принципе, не верно, хотя создаются они, как и любое другое ПО, в рамках той или иной операционной системы и ориентированы, обычно, на выполнение загрузки в первую очередь этой самой "материнской" ОС. Но "обычно" не означает "всегда". Прежде всего, это не относится к вычислительным системам, не использующим операционную систему вообще: многие однокристальные ЭВМ и все устройства на их основе, конечные автоматы и т.п. Эти системы не являются предметом нашего рассмотрения и упомянуты только для того, что бы проиллюстрировать, что загрузка (boot) - общее свойство вычислительных систем, а старт операционной системы IBM PC - частный случай загрузки.
Возможно, в таком взгляде на IBM PC есть своя логика. Во всяком случае, Erich Boleyn, первый разработчик GRUB, по роду своей основной деятельности имел дело прежде всего с вычислительными устройствами, обеспечивающими высокоскоростную передачу в сетях, и только потом - с IBM PC.
Прежде чем продолжить рассказ о GRand Unified Bootloader-е (именно из этих трех слов составлена аббревиатура GRUB), несколько слов о том, для кого это может быть интересно. Если Вы используете ОДНУ операционную систему ОДНОГО производителя (хотите, угадаю - какого?), то Вам это не нужно. Во всех остальных случаях - может пригодиться. Хотите иметь несколько win'9x на одном диске? Вообще, несколько разных операционных систем? Загрузку с любого из физических дисков (без выхода в BIOS Setup)? Универсальную загрузочную дискету? Попробовать альтернативу LILO? Если хотя бы один из ответов был положительным - читайте дальше.
Итак, дальнейшее уже будет иметь отношение исключительно к IBM PC. Архитектура этого, без сомнения, самого многочисленного клона компьютеров предполагает загрузку в ОЗУ с нулевого адреса так называемой MBR (Master Boot Record) - первого (или нулевого, в зависимости от того, с чего начинать считать) блока загрузочного устройства, и передачу на него управления. Загрузочными устройствами могут быть FDD, HDD или CD ROM, определяется это обычно в BIOS Setup. Во всех случаях размер MBR - 512 байт. Для MBR жесткого диска стандартизированы также возможное количество разделов (четыре, причем только один - расширенный (extended), который может содержать логические диски), структура и местоположение Partition Table - таблицы разделов, описывающей их геометрию, тип файловой системы и признаки активности (загружаемости).
Стандарт этот можно бы и игнорировать, но тогда никакое "чужеродное" ПО не сможет определить содержит ли диск хоть что-нибудь разумное. Поэтому и не игнорируют - даже MicroSoft, упорно "не замечающая" возможности существования нескольких первичных разделов. А вот содержимое MBR от "0" до Partition Table - не регламентировано. То есть, как раз исполняемые инструкции могут быть различными. И имеется под них всего-то 384 байта. Трудно разместить в таком объеме что-либо существенное - вместо этого размещают код очередного (в смысле очередности этапов загрузки) loader-a. В простейшем случае этот загрузчик загружает (уж простите за тавтологию) в память содержимое начального блока одного из primary (первичных), активного (bootable) раздела. Этот начальный блок, в отличие от начального блока диска называется уже не Master..., а просто - Boot Record).
Так это делалось от MS DOS вплоть до win'9x. В более сложных случаях инструкции, считанные из MBR, служат для того, что бы загрузить первичный загрузчик ОС, будь то NTLoader, LILO и т.п. Такой специальный загрузчик нужен для многих целей: во-первых, сама загрузка ОС может быть достаточно сложной, чтобы не "умещаться" в одном блоке; во-вторых, сколько-нибудь серьезная система предполагает возможность загрузки нескольких ядер (в простейшем случае хотя бы один дополнительный, аварийный (failsave) вариант); в-третьих, "хорошим тоном" считается сохранение возможности загрузки предыдущей версии ОС; ну и в-четвертых, хорошо бы предоставить пользователю возможность использовать еще одну ОС, хотя и не все производители ПО так считают.
Уже вышеприведенное описание показывает, что есть два принципиально различных способа загрузки. Первый - "тупой" или, выражаясь мягче, "аппаратный" - так называемая загрузка "цепочкой": последовательная загрузка начальных блоков сначала диска в целом, а затем - активного раздела. Недостатком этого способа являются архитектурные ограничения (не более четырех первичных разделов), и трудность размещения в одном блоке (512 байт) более-менее сложного ПО, обеспечивающего, например, начальный диалог с пользователем.
Альтернатива - "интеллектуальный" способ, предполагающий наличие специальной программы, имеющей доступ к файлам, расположенным на диске. Этот доступ позволяет вынести содержание и алгоритм работы меню загрузки в файлы, редактируемые пользователем, снимает все возможные ограничения на количество загружаемых систем или ядер одной и той же системы. Именно по этому пути и пошли разработчики всех современных менеджеров загрузки (из уважения, по-видимому, программы этого класса именуют уже не загрузчиками, а менеджерами).
Последний комментарий по поводу соотношения загрузчиков и ОС. Загрузчик не является частью ОС, поскольку не использует ее ресурсы (не может пока: ОС-то еще не загружена). Загрузчик зависим от ОС настолько, насколько его файлы "привязаны" к файловой системе данной ОС. Чем больше количество файловых систем, на которых могут находиться файлы загрузчика, тем больше его "вне-системность".
Обойдя ограничение четырех первичных разделов и невозможности загрузки разделов логических, разработчики менеджеров загрузки столкнулись с очередной трудностью - особенностями файловых систем, которые теперь уже были "небезразличны", и особенностями загрузки ядер различных ОС. Что касается файловых систем, то с этим "разобрались" быстро. Так, в исполнении авторов GRUB, программный "слой", обеспечивающий доступность файлов на томах 6-ти различных систем "уместился" в 6-ти файлах общим объемом чуть более 45-ти кбайт. А вот что касается загрузки ядер, то тут ожидать "консенсуса" не приходится. Но, на самом деле, такая цель и не ставилась.
В 1995 году, ядро Hurd (оригинальная ОС, включающая в себя множество инноваций, обсуждение которой выходит далеко за рамки данной статьи) достигло "готовности", когда нужно было уже задуматься о способе его загрузки. Вышеупомянутый Erich Boleyn в соавторстве с Brian Ford не стал "умножать" количество мало совместимых способов загрузки IBM PC, предложив вместо этого Multiboot Specification - спецификацию, обеспечивающую универсальный способ загрузки ядер ОС.
Вряд ли молодые люди рассчитывали на то, что, например, MicroSoft Co. приведет загрузку Windows XP к упомянутой спецификации, но для ядер Hurd, FreeBSD, NetBSD, OpenBSD и Linux мы получили действительно унифицированный подход. Приверженцам MicroSoft расстраиваться не пришлось: загрузка систем и загрузчиков, не совместимых с Multiboot Specification возможна по алгоритму "цепочки". Собственно говоря, все ОС MicroSoft, кроме NT, только так и загружались. Что же касается NT, то по "цепочке" загружается NTLoader, выполняя после своей загрузки все возложенные на него функции.
Дальше - больше. В 1999 году Gordon Matzigkeit и OKUJI Yoshinori представили GRUB как официальный пакет GNU. Круг участников проекта расширился, а функциональность пакета еще более возросла. Кроме изначально присущих уникальных возможностей, ориентированных, в основном, на разработчиков ядер ОС (и, как следствие, мало понятных большинству рядовых пользователей), на настоящий момент GRUB:
* принимает практически все форматы исполнимых файлов;
* обеспечивает загрузку ядер, совместимых и ограниченно совместимых со спецификацией Multiboot;
* поддерживает "цепочный" механизм для ОС и загрузчиков, не совместимых со спецификацией Multiboot;
* поддерживает загружаемые модули;
* поддерживает редактируемый текстовый конфигурационный файл;
* имеет меню-ориентированный и гибкий командный интерфейсы, удовлетворяющие, практически, любым запросам пользователя;
* поддерживает файловые системы: BSD FFS, DOS FAT16 и FAT32, Minix fs, Linux ext2fs, ReiserFS, и VSTa fs;
* обеспечивает автоматическую декомпрессию gzip-файлов;
* независим от геометрии дисков: переход к диску с другой трансляцией номеров блоков не потребует изменения конфигурации;
* определяет LBA-режим: если BIOS поддерживает LBA, GRUB пользуется этой поддержкой;
* поддерживает сетевую загрузку по TFTP-протоколу;
* поддерживает терминальный доступ по последовательному интерфейсу, т.е. может использоваться в без-консольных станциях.
Согласитесь: приведенный список - веская заявка на титул "GRand". Присмотримся поближе. Поскольку проект выполняется в рамках GNU, то информация о нем находится на http://www.gnu.org/software/grub/. Продукт и в настоящее время в стадии "alpha" (не пугайтесь, это определяется больше уровнем притязаний разработчиков, нежели работоспособностью уже сделанного), поэтому загрузить его можно только с ftp://alpha.gnu.org/gnu/grub/. Там находится три файла. На декабрь 2001-го это:
grub-0.9X.tar.gz - архив исходников, достаточных для построения GRUB в любой ОС клона unix;
grub-0.9X-i386-pc.ext2fs - образ загружаемой дискеты со всеми необходимыми файлами;
grub-0.9X-i386-pc.tar.gz - архив бинарных файлов, достаточных для загрузки (но не для инсталляции) в любой из поддерживаемых файловых систем.
Версия со временем, разумеется, изменится, но подход, будем надеяться, останется прежним.
Для unix-систем, безусловно, нужно использовать первый архив. Выполнив стандартные для unix configure && make && make check && make install, получаем три исполняемых файла в .../sbin, три man-страницы в .../man/man8, исчерпывающее info в .../info и восемь бинарных файлов в .../share/grub/i386-pc, образующих в разных комбинациях собственно bootloader.
Добавлять что-либо к info нет необходимости, но все это - только для unix. А где же "мультисистемность"? Оказывается - есть. Для инсталляции GRUB в любой из файловых систем на жестком или флоппи-диске нужно создать в корне этой файловой системы каталог /boot/grub (различия между прямым и обратным слэшем нивелируются) и перенести в него несколько файлов из архива grub-0.90-i386-pc.tar.gz: stage1 и stage2 - обязательно, а файлы с постфиксом stage1_5 - только те, которые обеспечат GRUB доступ к нужным файловым системам (которые - очевидно из их названий). Собственно инсталляцию, то есть запись кода загрузчика в MBR, выполнить тоже можно, но не нужно: разумнее последовать рекомендации авторов и выполнить инсталляцию непосредственно из grub, запущенного, например, с дискеты, созданной из grub-0.90-i386-pc.ext2fs. Под unix такая дискета делается командой:
dd if=./grub-0.90-i386-pc.ext2fs of=/dev/fd0
под DOS - с помощью известной утилиты rawrite, под win - rawwrite.
Загрузившись с дискеты, знакомимся с тем самым "гибким командным интерфейсом". Пользователи unix удивлены не будут: очень похоже на bash, остальным же, возможно, будет интересно познакомиться с памятью команд и авто-заполнением. Диалог начинается выводом перечня допустимых команд. Информацию по любой из команд можно получить, набрав help <имя команды>. В простейшем случае, для инсталляции GRUB потребуется всего две команды: root (hdn,m) и setup (hd0). Первая из команд указывает, где искать каталог /boot/grub с находящимися в нем файлами *stage*. Имя устройства всегда заключается в круглые скобки. n - номер диска, m - номер раздела. Способ обозначения разделов аналогичен принятому в unix (только нумерация начинается не с единицы, а с нуля), но для пользователей других систем может показаться "неочевидным".
На помощь придет авто заполнение команды: табуляция после root ( - выведет список допустимых устройств. Еще одна табуляция - и на экране список всех разделов выбранного диска. Может оказаться полезной команда find /boot/grub/stage1 - она-то уж точно укажет номер раздела, где создан искомый каталог. С помощью этой же команды можно искать любой файл на всех разделах диска и дискете. Не забывайте только, что path в данном случае - обязательный компонент имени. Поэтому, если файл должен быть в корневом каталоге раздела, не забудьте прямой слэш перед именем.
Команда setup выполнит все необходимые для инсталляции действия. В качестве параметра - диск, с которого и будет происходить загрузка. Однако с setup можно и не торопиться. Почему бы не проверить себя еще раз? Для этого команды загрузки ОС вводятся непосредственно в командном режиме (впоследствии эти команды составят конфигурационный файл). Для Linux это, например:
kernel (hd0,6)/boot/vmlinuz-up root=/dev/hda7
Команда загружает ядро, расположенное на третьем логическом диске расширенного раздела.
Для win'98 это будет выглядеть так:
makeactive
chainloader +1
Первая команда делает активным (загружаемым) раздел, выбранный командой root, вторая - загружает в память начальный загрузчик этого раздела.
Команда boot передает управление загруженным ядру или загрузчику. Если все в порядке - возвращаемся к setup и заканчиваем инсталляцию.
Вообще, перечень доступных команд достаточно обширен и всегда может быть выведен на экран нажатием <TAB>. Кроме команд, использование которых предполагает наличие специальных знаний (blocklist, debug, displayapm, displaymem, impsprobe, ioprobe, read, serial, setkey, terminal, testload, uppermem), имеются следующие группы команд:
* управления:
o boot - передать управление ядру, загруженному командой kernel или "чужому" загрузчику, загруженному командой chainloader,
o halt - выключить машину,
o help [команда] - выдать подсказку,
o quit - выйти из GRUB,
o reboot - перезагрузиться,
o pause - ждать нажатия клавиши;
* работы с файлами:
o cat - вывести на экран,
o cmp - сравнить содержимое двух файлов;
* управления доступом:
o password - обычно помещается в конфигурационном файле и при достижении ее требует ввода пароля,
o lock - блокировать выполнение команд для неидентифицированного пользователя;
* модификации разделов:
o partnew - создать первичный раздел,
o partype - изменить тип раздела;
* настройки внешнего вида:
o color - задать цвета меню,
o vbeprobe - определить и вывести доступные режимы видеоадаптера,
o testvbe MODE - тестировать режим MODE видеоадаптера.
Приведенный список команд не полон, но более подробное обсуждение было бы слишком объемным, тогда как еще не рассмотрены команды, с помощью которых, собственно, и выполняются варианты загрузки. Эти же команды являются основным содержанием конфигурационного файла. Файл этот называется menu.lst и располагается все в том же /boot/grub. В начале файла обычно размещаются команды задания цветов:
color light-gray/blue black/light-gray
Первая пара цветов определяет основной и фоновый цвета для "не выбранных" позиций меню, вторая - для "выбранных".
Время (в секундах) от момента вывода меню до выполнения позиции, определенной, как "умолчание", задается командой:
timeout 10
Позиция "по умолчанию" задается, как:
default 0
Если загрузка "по умолчанию" по какой-либо причине невозможна, то будет предпринята попытка выполнить позицию, указанную в команде:
fallback 1
Цифры, определяющие позицию меню, могут быть, разумеется, любыми. Обратите внимание только на нумерацию - с нуля.
Описание каждой из позиций меню начинается с команды:
title text
где text - остаток строки от первого "непробельного" символа после title.
Группа команд одной позиции меню в обязательном порядке имеет уже упомянутую команду root. ОС, хотя бы частично соответствующие Multiboot Specification, загружаются командой kernel, причем в строке можно указывать дополнительные параметры. Так, команда
kernel (hd0,6)/boot/vmlinuz-up root=/dev/hda7 hdd=ide-scsi
vga=788
загрузит Linux, корневым каталогом назначит /dev/hda7, включит эмуляцию ide-scsi, нужную для пишущего привода CD и переведет видеоадаптер в режим 800х600 графической консоли, для работы с так называемым frame buffer device.
Для ОС, не соответствующих Multiboot Specification, сначала взводится бит "активности" раздела, выбранного командой root:
makeactive
а, затем, методом "цепочки" загружается собственный загрузчик данной ОС:
chainloader +1
Поскольку ОС семейства win'9x не могут быть загружены из соседних разделов (вне зависимости от флага активности грузится все равно первый из разделов), для их загрузки нужно использовать команды hide и unhide. Так, если первый и второй первичные разделы содержат win'9x, то для загрузки второй системы нужно включить в menu.lst следующие команды:
hide (hd0,0)
unhide (hd0,1)
root (hd0,1)
makeactive
chainloader +1
Аргументы hide, unhide и root для загрузки первой системы, думаю - очевидны.
Еще одна трудность с ОС от MicroSoft - неспособность грузиться со второго и последующих дисков. Для ее преодоления применяют технику "свопирования" (swapping technique), или, проще - "подмены". Так же, собственно, поступает и BIOS Setup, но зачем же обращаться к нему, если всего две строки в menu.lst выполнят ту же операцию:
map (hd0) (hd1)
map (hd1) (hd0)
Во всех случаях не лишним будет сначала загрузиться с дискеты, запустить grub и проверить, соответствует ли результат выбранных команд ожидаемому. В командном режиме существует специальная команда, загружающая созданный menu-файл:
configfile FILE
Еще один совет - для начала инсталлировать GRUB на дискете. Скорость загрузки с дискеты радует, что, собственно, и не удивительно: общий объем загружаемых файлов - менее 100 кбайт.
Ну, и последняя рекомендация, содержащаяся в инструкциях абсолютно ко всем менеджерам загрузки: до инсталляции нового менеджера загрузки сохраните MBR! В unix это можно сделать командой:
dd if=/dev/hd0 of=your_file bs=512 count=1
в DOS - с помощью Norton DiskDoctor например.
Сравнительный анализ различных менеджеров загрузки выходит за рамки данной статьи, но даже без такого анализа можно, наверное, согласиться, что "GRand" - вполне заслуженный титул для рассматриваемого пакета. GRUB - даже больше, чем "unified bootloader". Дискета с ним позволит проанализировать разделы потерявшего способность к загрузке винчестера, загрузить любой из первичных разделов или любое из ядер Hurd, FreeBSD, NetBSD, OpenBSD или Linux. Возможно и более "изощренное" вмешательство в структуру разделов диска, но это, пожалуй, уже другая тема.
Введение для подоконников
Зачем?
Как-то "сложилось по жизни", что на IBM PC мне всегда требовалось более одной операционной системы. Сама архитектура этого компьютера такую мультизагрузку вполне допускает, род моих занятий - программист, так что особых проблем упомянутая потребность не вызывала. В тех же случаях, когда подобная мультизагрузка требовалась кому-то ещё, я рекомендовал xboot Ильи Евсеева. С приходом Pentium-II инсталлятор xboot пришлось слегка подправить по поводу run-time error 202 (ну, не предполагали разработчики TurboPascal, что так быстро всё случится), за что, пусть с опозданием, приношу извинения автору: несанкционированная модификация кода, всё же. А больше ничего и не требовалось.
Познакомившись года четыре назад с Linux, я узнал, что, кроме загрузки первичных разделов (реальных или виртуальных), загружать можно и ядра операционных систем. Причём, этих уж может быть сколько угодно: существующее ограничение на количество первичных разделов значения, в данном случае, не имеет. Дальше - больше. Оказывается, существует спецификация множественной загрузки (multiboot specification), и если бы производители ОС её придерживались, то мультизагрузка могла бы стать функцией BIOS, например. Это, однако, - из области фантазий. Пока, во всяком случае.
Постепенно примкнув к лагерю сторонников ПО с открытым исходным кодом (и в соответствии с принципами этого лагеря), я несколько раз делился опытом на виртуальных страницах различных сайтов. И вот что интересно: больше всего вопросов задали мне в связи с моим вариантом описания мультизагрузчика GRUB (GRand Unified Bootloader). Причём спрашивали не собратья linux-оиды, а именно пользователи ОС от MicroSoft. К сожалению, мои советы по поводу использования GRUB помогали им не так уж часто. И не потому, что этот мультизагрузчик плох, отнюдь, а потому, что, кроме возможности загружать УЖЕ СУЩЕСТВУЮЩИЕ на винчестере ОС, уважаемым корреспондентам требовалась ещё и возможность создавать СОСУЩЕСТВУЮЩИЕ ОС от MicroSoft на одном и том же винчестере. А вот это в прямые функции GRUB никак не входит. Сам же производитель такую возможность пользователям не предоставляет: ну, не могли они предположить такой удачи, чтобы для одного компьютера несколько ОС покупалось. Upgrade со скидкой - предположили, а две версии одной ОС, но разной, скажем, локализации - нет. Или просто две одинаковых: одну - сынишке-геймеру, другую - себе для работы...
Сожаление моё (а может - раздражение из-за необходимости повторять одну и ту же информацию, с каждым разом кажущуюся всё более банальной) постепенно достигло уровня, когда я решил предпринять ещё одну попытку разъяснения всем желающим возможности использования на одном IBM PC нескольких операционных систем производства MicroSoft. "Ещё одну", потому, что документация к любому мультизагрузчику предпринимает такую попытку в обязательном порядке, жаль только, мало, кто эту документацию читает, если судить по отзывам на эти самые мультизагрузчики. А "MicroSoft" потому, что ОС unix-клона и так предоставляют все необходимые для мультизагрузки средства, да и пользователи их, в большинстве своём, лучше представляют себе организацию данных на винчестере: и не обязательно из-за "повышенной" грамотности - по необходимости, быть может.
Итак, оставим в стороне multiboot specification и vmlinuz (традиционное название ядра Linux): просто добьёмся существования на одном винчестере двух-трёх "непритязательных" ОС: DOS, win'95 и win'98. Для решения этой задачи потребуются некоторые знания и инструментарий. И то и другое - в минимальном количестве. В стиле MicroSoft, так сказать. Дабы пользователь "не утомился".
Каким образом?
Что касается знаний, то без них, к сожалению, не обойтись: слишком скудны средства, которыми располагает персональный компьютер в момент загрузки. Поэтому и рассчитывать на исчерпывающе-содержательный интерфейс мультизагрузчиков не приходится. Если система "не грузится", то некому поведать языком "интуитивно-понятного интерфейса", почему это случилось. Приходится рассчитывать на аскетическое ПО, размещающееся, как правило, на дискете, и на собственные знания. Минимальный набор знаний, необходимых для осуществления самостоятельных осмысленных операций над разделами диска IBM PC, укладывается в сравнительно небольшое число постулатов:
* загрузка IBM PC всегда начинается с переноса в память содержимого нулевого блока загрузочного устройства (HDD, FDD, CDROM - как уж в BIOS Setup задано) и передачи на него управления. Размер блока - всего 512 байт и для всех устройств, кроме HDD, ничего, кроме инструкций загрузки следующей порции кода, в нём не содержится;
* HDD же, по замыслу создателей IBM PC, может иметь несколько загружаемых разделов. Поэтому часть главной загрузочной записи (master boot record - MBR), как уважительно назвали нулевой блок винчестера, отведена под таблицу разделов (Partition Table);
* таблица эта содержит описание не более чем четырёх первичных (primary) разделов, причём только один из них может быть расширенным (extended), в котором, в свою очередь, могут содержаться свои разделы. Эти разделы, в отличие от разделов первичных, называются логическими. Число логических разделов не ограничено;
* описание каждого первичного раздела, кроме данных о его физическом размещении, содержит пару весьма существенных байт: байт активности (загружаемости) раздела и байт типа файловой системы. Первый из этих двух байт принимает всего два значения: 0x80 или 000 (для загружаемого и не загружаемого разделов, соответственно). Типов же файловых систем существует значительно больше. Современному приверженцу MicroSoft достаточно знания следующих:
o 004 - FAT16, объёмом менее 504 MB
o 005 - расширенный раздел, заканчивающийся ниже 8 GB
o 006 - FAT16, объёмом менее 2 GB, заканчивающийся ниже 8 GB
o 007 - Windows NT NTFS
o 00B - FAT32, заканчивающийся ниже 8 GB
o 00C - FAT32, заканчивающийся выше 8 GB (как 00B, но для LBA)
o 00E - FAT16, объёмом менее 2 GB, заканчивающийся выше 8 GB (как 0х06, но для LBA)
o 00F - расширенный раздел, объёмом более 8 GB или заканчивающийся выше 8 GB (как 0х05, но для LBA)
o 0xFF - таблица дефектных блоков Xenix
Типы 00B .. 00F в настоящее время - преобладающие, как преобладающий способ адресации блоков диска - LBA.
Тип "таблица дефектных блоков Xenix" используется для "маскировки" разделов, а зачем такая "маскировка" нужна, станет ясно чуть позднее;
* прибавление 0x10 к идентификатору типа раздела делает его "скрытым" (hidden). Правда, на эту "скрытость" MicroSoft перестала обращать внимание, начиная от win'2000.
* исполняемый код MBR, в отличие от таблицы разделов, не стандартизирован и разные ОС относятся к нему по разному: некоторые при инсталляции переспрашивают, можно ли перезаписать MBR, а некоторые - нет. Младшие MS Windows - нет. Спасибо, хоть таблицу разделов не затирают. Отсюда вывод: MBR нужно уметь сохранять, восстанавливать, а лучше - формировать заново;
* и, наконец, схема загрузки, исповедуемая MicroSoft. Порядок изложения - "обратный". То есть, от загрузки собственно ОС до операций BIOS, выполняемых по включению компьютера:
o ОС загружается начальным загрузчиком, записанным в нулевой блок первичного раздела, в который инсталлировалась ОС (в отличие от MBR, он уже не "master", а просто "boot record"). Начальный загрузчик записывается ОС при инсталляции;
o начальный загрузчик, в свою очередь, загружается главным загрузчиком (тем, что записан в MBR);
o код главного загрузчика, записываемый в MBR ОС MicroSoft, бесхитростен: найти в таблице разделов первый из загружаемых первичных, считать в память его начальный загрузчик и передать на него управление;
o ну, а главный загрузчик, если помните, считывается в память самим BIOS.
В случае с NT в результате описанных выше действий запускается не ОС, а NTLoader - собственный мультизагрузчик NT.
Действия над MBR, выполняемые ОС при инсталляции (в том случае, если MBR всё-таки переписывается, разумеется), таковы:
o переписать исполняемый код MBR;
o установить бит загружаемости (активности) раздела, в котором инсталлируется ОС, сбросив его при этом у всех остальных первичных разделов.
В принципе, из вышеизложенного уже можно догадаться, что нужно сделать для достижения поставленной задачи:
* инсталлировать первую систему, не занимая ею всё дисковое пространство, разумеется;
* "маскировать" первую систему;
* инсталлировать вторую систему;
* при желании: таким же образом - третью;
* "демаскировать" все установленные системы;
* инсталлировать мультизагрузчик.
С помощью чего?
Теперь осталось выяснить: как конкретно это сделать. Переходим к инструментарию. Существует довольно много программ, с помощью которых можно редактировать MBR и, в частности, таблицу разделов. Большинству пользователей MS Windows наверняка известен Norton Disk Doctor, доживший уже до девятой, если память не изменяет, версии.
Список известных мультизагрузчиков тоже не так уж мал. А вот продукт, достаточный сам по себе для решения поставленной задачи, известен мне только один. Это GRUB - GRand Unified Bootloader. Изначально, автор - Erich Boleyn, а в настоящее время проект развивается как часть GNU - известного "бастиона" Open Source. Именно на сайте этой уважаемой организации находится страничка GRUB: http://www.gnu.org/software/grub, а на её ftp-сервере всегда можно скачать последнюю версию пакета.
GRUB, безусловно, достоин отдельного разговора, но для наших "минималистских" целей достаточно будет рассказать о пяти-шести из почти шести десятков его команд - да простят меня авторы. Приверженцам MicroSoft я даже скачивать дистрибутив GRUB не рекомендую: проще воспользоваться его загрузочной дискетой, подготовленной мной специально для них на дискете в формате FAT (подобная дискета входит и в состав дистрибутива, только файлов на ней, не имеющих отношения к ОС от MicroSoft, много больше и прочитать её под DOS/Windows - затруднительно). Архивированный образ дискеты лежит здесь, а получить из образа дискету можно с помощью замечательной программы rawwrite, которую, пользуясь случаем, я настоятельно всем рекомендую. Размер архива - очень скромный - чуть более 50кБ.
Приступим!
Вот мы и "во всеоружии". Начали:
* описание инсталляции ОС пропустим: разные они, да и не об этом речь. Замечу только, что первичный раздел для устанавливаемой ОС лучше готовить её же средствами: практически никаких шансов ошибиться. Поскольку, по мнению fdisk-a от MicroSoft (а именно он разбивает диск на разделы) первичный (primary) раздел может быть только один, то придётся с этим для начала согласиться. Размер раздела выберите минимально достаточным. Расширенный раздел можно пока не создавать;
* убедившись в работоспособности первой инсталлированной системы, загрузимся с дискеты GRUB. Если дискета оригинальная, то Вы сразу попадёте в командный режим (на это укажет подсказка "grub>"), а если воспользовались моим предложением, то на экране появится меню загрузки. С меню разберёмся позднее, а для перехода в командный режим нужно нажать "с", о чём, кстати, напоминает и присутствующая на экране подсказка. Набираем:
grub>root (<Tab>
где <Tab> - подразумевает нажатие клавиши табуляции.
В ответ на это вы получите варианты продолжения команды. Если у вас только один винчестер, то вариантов будет всего два: fd0 и hd0. Отмечаем: так называются и нумеруются (с нуля!) в GRUB дисковые устройства. Продолжим набор в соответствии с нашим планом:
grub>root (hd0,<Tab>
В ответ мы получим перечень разделов диска, выбор из которых возможен. Поскольку раздел у нас пока один, то и в перечне только одна позиция. Нажимаем <Esc>, поскольку продолжать команду не нужно: всё проделанное было нужно лишь для того, что бы, заставляя GRUB выполнять автозаполнение команды, "выудить" у него информацию о разделах. Что и достигнуто. Запоминаем (лучше - записываем), что первая ОС инсталлирована в разделе (hd0,0) (нотация - GRUB), и тип её - 00b, например (у Вас, разумеется, может быть другой). Переходим к следующему пункту;
* "маскируем" первую систему командой:
grub>parttype (hd0,0) 0xff
Это уже нормальная команда и завершать её нужно вводом Enter. Если Вы ещё не догадались, то скажу, что таким образом мы поменяли байт-идентификатор типа файловой системы раздела на 0xff. С этого момента вполне нормальная система будет видеться всеми прочими, как нечто абсолютно чуждое (даже Xenix, которого все прочие будут полагать создателем этого раздела, посчитает её списком дефектных блоков);
* инсталлируем следующую систему. Инсталлятор, конечно, обнаружит на диске некоторый "Non-DOS partition", но препятствием к инсталляции это не будет. Хорошо также и то, что инсталлируемая ОС никак не модифицирует чужой раздел: спасибо MicroSoft хоть за это. Все рекомендации аналогичны приведённым для первой инсталляции;
* если Вам понравилось, то аналогичным образом Вы можете установить и третью систему, предварительно "замаскировав" вторую. А вот четвёртый раздел рекомендуется всё же сделать расширенным - пригодится. На этом этапе - самое время;
* теперь разделы можно "демаскировать". Быть может, это и лишнее, но напомню, что делается это командой:
grub>parttype (hd0,n) 0xNN
где n - номер демаскируемого раздела, а 0xNN - действительный тип его файловой системы (я надеюсь, Вы ещё не потеряли бумажку с записями об этом). Нетрудно догадаться, что после "демаскирования" грузиться будет всегда система, инсталлированная последней. Большего от кода в MBR добиться не удастся: пора переходить к подготовке мультизагрузки;
* у GRUB есть одно достоинство: меню допустимых загрузок и их алгоритмы хранятся в обычном текстовом файле. Это, безусловно, достоинство, поскольку позволяет изменять загрузку, модифицируя всего лишь один очень небольшой текстовый файл, но, как и многие достоинства, это тоже имеет свою "оборотную сторону". Состоит эта "сторона" в том, что этот самый файл должен находиться в разделе, файловую систему, которой умеет "читать" GRUB. Список читаемых файловых систем довольно обширен, да вот только NTFS в него не входит. Отсюда вывод: всё нужное для GRUB нужно размещать в разделе FAT. Надеюсь, хоть один такой у Вас имеется. Создаём в его корневом каталоге подкаталог boot/grub (не обращайте внимания на "косые": GRUB не обращает внимания на то, прямые они или обратные - и мы не будем) и переписываем в него файлы из аналогичного подкаталога дискеты. Заметьте, на котором из разделов находится этот подкаталог;
* опять загружаемся с дискеты GRUB (хорошо, что времени на это требуется заметно меньше, чем для загрузки, скажем, DOS) и выполняем следующие команды:
grub>root (hd0,n)
grub>setup (hd0)
где n - номер раздела, в котором находится подкаталог boot/grub.
Последние штрихи
Если у Вас современный винчестер, то почти наверняка GRUB сохранил весь необходимый ему для работы код в блоках нулевой дорожки, соседствующих с MBR (нулевая дорожка не используется операционными системами). Если сообщение об этом появилось на экране во время выполнения команды setup, то все файлы подкаталога boot/grub можно теперь удалить. Кроме menu.lst. Точнее, его тоже - можно, но при этом нужно позаботиться о переносе содержимого этого файла в какие-нибудь свободные блоки на диске (а хоть бы и на той же нулевой дорожке), а номера этих блоков перечислить в команде install. Как это сделать под Linux - не интересно пользователю MS Windows, а средствами самой MicroSoft этого сделать и вовсе нельзя. Поэтому лучше оставим menu.lst на месте и перейдем к анализу его содержимого на примере варианта с предложенной Вам дискеты. Вообще-то, файл этот достаточно, на мой взгляд, прокомментирован. И даже, для удобства приверженцев MicroSoft, - в кодировке win-1251. Но некоторые пояснения, быть может, и не помешают:
* команды установочной сессии:
o timeout 10 - задаётся число секунд, после которого стартует загрузка "по умолчанию", нажатие на любую клавишу прерывает отсчёт. С этого момента "само собой" ничего не произойдёт: GRUB ожидает команды или выбора позиции меню;
o color light-gray/blue black/light-gray - задаются цвета меню: цвет символов/фона для не выбранной и выбранной позиций меню;
o default 0 - задаётся та самая позиция меню "по умолчанию". Позиции меню, как можно заметить, тоже нумеруются с "нуля". Приведённая строка, кстати, смысла не имеет: в её отсутствие именно нулевая позиция меню и считается позицией "по умолчанию". Но вот если бы цифра была другой...
* команда title menu item - всегда начинает описание варианта загрузки. Текст после title станет текстом соответствующей позиции меню;
* все ОС MicroSoft загружаются следующими командами:
root (hdm,n)
makeactive
chainloader +1
где m - номер диска, n - номер раздела. Оба нумеруются с "нуля".
Испытываю искушение начать описывать реальный смысл приведённых команд... Но "наступаю на горло собственной песне", поскольку отдаю себе отчёт в том, что среднестатистическому пользователю MS Windows это ни к чему, а я, в свою очередь, обещал не обременять его излишними знаниями. Опять же - в стиле MicroSoft.
Приложение
Отредактировав menu.lst, Вы получаете законченную систему с мультизагрузкой. Поздравляю. Надеюсь, предложенный мной путь не показался Вам слишком трудным - проще не смог, уж не взыщите. А приведённые ниже советы можно прочитать "чисто из любопытства" или в том случае, если Вы столкнётесь с проблемой, для разрешения которой знаний у Вас окажется недостаточно. Можно рассматривать их, как мини-FAQ к основному материалу. Итак:
* не потеряйте дискету GRUB. Ваш menu.lst никуда не денется, если только Вы сами его ненароком не уничтожите, а вот исполняемый код MBR (который в настоящий момент представляет собой ни что иное, как stage1 GRUB) рано или поздно будет уничтожен очередной реинсталляцией продукта MicroSoft. К счастью, установка мультизагрузчика отнимает не более минуты, вот только дискета GRUB при этом - обязательное условие;
* когда разделов на Вашем диске станет много, их таблица, выводимая GRUB, как автозаполнение команды root, не должна ввести Вас в заблуждение множеством разделов типа 00B или 00C. Все разделы с номерами старше трёх - логические и, хотя типы их такие же, как у разделов первичных, загружаться они не могут. На самом деле, с помощью GRUB - могут, если будут содержать в загрузочной записи (boot record) код загрузки операционной системы. Только вот Microsoft не предоставляет средств инсталляции своих ОС в логические разделы. Если же Вы воспользуетесь средствами копирования разделов независимых производителей и не ошибётесь при задании идентификатора файловой системы, то преодоление ограничения на количество загружаемых разделов перестанет быть неразрешимой задачей;
* не забывайте о существовании командного режима. В Вашем распоряжении больше полусотни команд, среди которых сравнение и поиск файлов, средства загрузки по сети и многое другое, о чём я не писал, дабы преждевременно не утомить избалованных "интуитивно понятным интерфейсом". help и help имя_команды - лучшие помощники при использовании командного режима;
* имея несколько разделов, Вам, возможно, захочется один из них использовать в качестве "подопытного" - того, на котором можно опробовать "сомнительное" ПО. Результатом таких проб и ошибок часто становится крах системы. Сохраните заблаговременно образ "свежеинсталлированнной" системы (Ghost от Symantec или DriveImage от PowerQwest - вполне подходящие для этого средства) - пригодится;
* существует "туповатый" аналог команды root - rootnoverify. Разница между ними в том, что rootnoverify просто объявляет указанный раздел "разделом по умолчанию", даже не пытаясь читать его. Все последующие команды будут подразумевать именно этот раздел. Пробовать можно смело: хуже не будет;
* если команду chainloader использовать с опцией --force, то не будет проверяться так называемая "сигнатура" - последние два байта загрузчика раздела (boot loader), которые всегда должны быть равны 0x55 0xAA. Мне, признаться, не встречались исправные загрузчики с неверной сигнатурой, но, может быть, Вам повезёт больше;
* и первичные, и логические разделы можно "скрывать" (hide), устанавливая четвёртый бит в байте типа системы (тот самый, который MicroSoft игнорирует, начиная от win'2000). Вставив, например, в некоторую секцию загрузки команды:
hide (hd0,1)
hide (hd1,1)
unhide (hd0,0)
мы "скроем" при её загрузке вторые разделы первого и второго дисков и, напротив, "откроем" первый раздел первого диска.
* существует возможность выводить меню GRUB в графическом режиме на фоне какой-либо картинки. Для этого используется следующая команда установочной сессии:
splashimage=(hd0,0)/boot/grub/splash.xpm.gz
номер диска и раздела могут быть, разумеется, любыми. splash.xpm.gz - сжатый (gziped) файл "заставки". Команду задания цветов меню color в этом случае лучше исключить: всё равно не сработает. Формат "заставки", к сожалению, задан жёстко: 640х480, 14 цветов, xpm-кодирование. К сожалению, потому, что как простейший из архиваторов gzip, так и графический формат xpm не являются "естественными" в среде Microsoft Windows. К тому же, команда splashimage не включена в вариант GRUB, предоставляемый GNU, а только в те, которыми комплектуются дистрибутивы RedHat или ALT Linux, например. Красота, как это часто бывает, и в этом случае "требует жертв";
* ни одна ОС от MicroSoft, кроме NT, не может быть загружена со второго диска. Нужно выходить в BIOS Setup, менять устройство загрузки и т.д. и т.п. GRUB предоставляет альтернативу. Команды:
map (hd0) (hd1)
map (hd1) (hd0)
root (hd0,0)
makeactive
chainloader +1
загрузят ОС из первого раздела второго диска. Обратите внимание, что команды map "меняют местами" диски даже в представлении GRUB: второй диск становится после их выполнения hd0, а не hd1. Также, собственно, поступает и BIOS;
* символьные имена дисковых устройств, доставшиеся современным ОС от MicroSoft "по наследству" от MS DOS, приносят, подчас, немало неудобств. И дело, конечно, не в том, буквами или цифрами обозначать логические устройства, а в том, детерминирована ли связь между наименованием логического устройства и его физической сущностью. У MicroSoft - нет. Сами-то они "буковки" эти не шибко "жалуют" - загляните хотя бы в NT-шный boot.ini: нумерация дисков и разделов вполне очевидна. Но для пользователя... Наблюдали ли Вы изменение порядка именования устройств при подключении второго диска или изменении структуры разделов? Об этом-то и речь. Как будто второй логический раздел расширенного раздела первого диска изменился после подключения второго диска. Явно - нет, но называется теперь иначе. Для борьбы с этим явлением рекомендуется задавать в BIOS второй, подключаемый диск как "отсутствующий" (not installed). Система всё равно обнаружит его, но на более позднем этапе и "буковки" присвоит его разделам следующие за "буковками", занятыми разделами первого диска.
C NT - получше. Имена разделам можно присваивать самому, а в последних версиях уже появилась возможность монтирования "a la unix", когда новое устройство становится как бы частью уже существующего дерева каталогов - и никаких "буковок". Но... Всё это не относится к разделу системному - тому, на котором сама NT инсталлирована. А потребность такая не исключена. Реинсталляция NT после переноса на другой диск или инсталляция "поверх" (с целью спасти нужные файлы не ко времени "рухнувшей" системы) с высокой долей вероятности дадут Вам новое имя системного раздела. А это неудобно, принимая во внимание количество ссылок в registry на имя старое. Тут уж придётся действовать "отмычкой": с помощью regedit переименуйте соответствующий ключ в секции:
\\HKLM\System\MountedDevices\
Подробнее не описываю: знающему достаточно, а не знающему, что такое regedit, сначала лучше с ним поближе познакомиться, и лишь потом переходить к редактированию registry.
* первичные разделы и логические разделы расширенного раздела нумеруются в порядке создания, а не в соответствии с их физическим расположением. Это одно и то же, но только до первого удаления уже существующего раздела (а кто помешает нам это сделать?). Можно бы об этом и не задумываться, но некоторое ПО почему-то настойчиво предлагает ренумеровать разделы в соответствии с их физическим порядком, а некоторое - просто выполняет такую ренумерацию, даже не проинформировав об этом пользователя. Полагаю, не нужно объяснять, что номера разделов в menu.lst после этого могут указывать уже не "туда, куда следует". Придётся вспомнить о командном режиме, определении действительных типов файловых систем, после чего отредактировать menu.lst;
* все описанные операции над таблицей разделов не касались изменения размеров разделов существующих. И это естественно: GRUB не предлагает такой возможности, да и знаний тут требуется побольше. Если же Вам когда-нибудь всё-таки придётся вручную модифицировать эти размеры (восстанавливая MBR после CIH-атаки, например), то помните, что в таблице они задаются двумя способами: старым, с указанием значений номеров цилиндра, головки и сектора для начала и конца раздела (CHS), и новым - с указанием логического номера стартового блока раздела и его длины в блоках. Нетрудно догадаться, что второй является одновременно и единственно правильным для LBA (Logical Block Addressing) режима. Для разделов, физические параметры которых уже невозможно описать формулой "цилиндр - головка - сектор" (места, отведённого в своё время создателями IBM PC для хранения этих данных просто недостаточно для описания параметров современных винчестеров), поля CHS всё же заполняются, указывая, обычно, на близкий к максимально адресуемому в рамках CHS.
Эпилог
Разумеется, описанный способ создания системы с мультизагрузкой - не единственный. Лет пять назад, устав от необходимости несколько раз запускать Disk Editor, пока подготавливаемый к продаже компьютер не обретёт запрошенную мультисистемность, я написал четыре крошечные утилитки для сохранения и восстановления MBR, а также для просмотра и модификации пресловутых четырёх пар байт таблицы разделов. Используя возможности создания меню средствами config.sys и autoexec.bat, loadlin - для загрузки Linux из-под DOS и эти самые утилитки, также вполне можно было создать систему с мультизагрузкой. Вывод: важнее всё-таки знать, что нужно делать, а средства осуществления - найдутся.
Вот, собственно, и всё о моём любимом мультизагрузчике в варианте изложения для приверженцев MS Windows. Побольше любопытства, хладнокровия при операциях на MBR и - успехов!
Расширение для POSIX'ивистов
"С чего начинается..."
Жизнь вычислительных систем изрядно скучна. Это у нас, если верить Ф.Энгельсу, жизнь - это, прежде всего самовоспроизведение, а у них... Оператор за оператором, иногда - прерывания, да и те не всегда "по делу". К тому же, всё это (спасибо Джону фон Нейману) в одном и том же пространстве: и инструкции, и данные... Главное - не сбиться. С самого начала. С загрузки, то есть. Есть, конечно, системы, не использующие динамических данных, и поэтому не нуждающиеся в ОЗУ, но, по нынешним временам, это - экзотика.
Для большинства вычислительных систем пространство, в котором находятся эти самые инструкции и данные - это пространство ОЗУ. Следовательно, прежде чем "жить", вычислительной системе нужно загрузить в ОЗУ нечто и передать на него управление. Легко сказать, если единственное, что умеешь - это выполнять инструкции, УЖЕ находящиеся в памяти. Именно об этом сказано: "поднять себя за шнурки собственных ботинок". И словечко подходящее подобрали: "boot". Наше "загрузить" - только полдела описывает. А вот: "с носка её!". К счастью, память бывает не только оперативная. В ПЗУ, например, программу загрузки можно записать при производстве ЭВМ, а она уже остальное загрузит... Только вот, что - остальное? Операционных систем много больше, чем аппаратных платформ. Не исключено также, что аппаратура переживёт ПО... Хотя может - и наоборот, конечно. Требуется соглашение и инициатором его, как правило, выступает производитель ЭВМ. Для персональных компьютеров это - IBM, как известно.
В первом приближении соглашение о загрузке IBM PC выглядит достаточно просто: загрузка происходит с блочного устройства и состоит в переносе в память "нулевого" блока этого самого устройства с последующей передачей на него управления. Размер/sлока - 512 байт: не шибко "разгуляешься". Блок этот назвали boot record (загрузочная запись), а для жёсткого диска, который предполагалось разделить на несколько разделов, добавили эпитет master. Отсюда аббревиатура MBR (master boot record) - главная загрузочная запись, по-нашему. Не захотели, стало быть, конструкторы от IBM оставлять своё детище заведомо "моноосным". То ли предчувствовали грядущую размолвку с MicroSoft, то ли действительно дорожили идеалами свободной конкуренции, однако договорились: часть MBR отвести под таблицу, описывающую максимум четыре раздела, любой из которых может загружаться. Таблицу эту, "не мудрствуя лукаво", так и назвали - partition table (таблица разделов). Описывает она физические размеры и расположение разделов (с некоторых пор: с учётом логической адресации блоков - LBA), типы их файловых систем и, так называемую, "активность" - признак загружаемости: если равноправных разделов больше одного, то надо же знать, который именно загружается. Технические детали этого описания опустим: "ищущий да обрящет".
За вычетом таблицы разделов в MBR остаётся всего-то 384 байта. Они-то и стали "полем боя" для программок, называемых загрузчиками. Не серьёзно, на первый взгляд. Но если эти без малого четыре сотни байт определяют, какая ОС загружается дальше... Не к ночи будь названа, MicroSoft определилась моментально: возможность "потеснить" потенциальных конкурентов намного важнее количества первичных разделов или какой-то там мультизагрузки. Нет их - и всё тут. Сработало. Абсолютное большинство пользователей IBM PC в "обёртке" от MicroSoft понятия не имеют о мультизагрузке, да и о разделах вообще. Естественно, как реакция, тут же нашлись желающие продавать "потенциально" существующую мультизагрузку. Их продукты стали называть "менеджерами загрузки", но... MicroSoft почти не оставила им шансов на выживание, "походя" переписывая MBR при каждой инсталляции. Учитывая то, что реинсталляция MS Windows требуется приблизительно так же часто, как размораживание холодильника (говорят, и эффект тот же: помогает, но ненадолго), не удивительно, что сохранять при этом работающим мультизагрузчик удавалось только самым компетентным.
Другое дело - Open Source. Здесь никто никого не теснил. Напротив: обязательным казалось предоставление возможности загрузки как можно большему числу ОС. MS Windows - в том числе. Стандартный загрузчик Linux (LILO - LInux LOader) для линуксоидов практически всем хорош: не пугает их ни необходимость переустановки LILO после каждой реконфигурации, ни то, что для такой переустановки нужно сначала загрузить Linux. Последним словом в истории мультизагрузчиков LILO, однако, не стал...
GRUB, как загрузчик "всех времён..."
Как, собственно, и Linux - не единственная ОС, созданная и развиваемая сторонниками Open Source. Я бы даже сказал: далеко не единственная. Причём, кроме достаточно близких "родственников" по линии UNIX, есть и "оригиналы", как HURD, например. Вернёмся, однако, к загрузчикам. Из сказанного следует, что раз появляются принципиально новые ОС, то возникает потребность и в новых загрузчиках. Так, в 1995 году Erich Boleyn в попытках загрузить GNU Hurd решил создать новый загрузчик, вместо того, чтобы модифицировать загрузчик FreeBSD. А для того, чтобы работа эта не пропала "втуне", в содружестве с Brian Ford была разработана спецификация мультизагрузки (Multiboot Specification). Любое ядро, построенное в соответствии с данной спецификацией может быть загружено соответствующим мультизагрузчиком. Первым из таковых и стал GRUB - GRand Unified Bootloader. Сильные стороны Open Source можно демонстрировать, среди прочего, и на примере GRUB: хорошие разработки не пропадают. Когда в 1999 году Erich Boleyn перестал уделять своему детищу достаточно внимания, Gordon Matzigkeit и Yoshinori K. Okuji оформили GRUB как официальный пакет GNU, каким он по сей день и является.
На настоящий момент GRUB входит практически во все дистрибутивы Linux, для большинства из них является "загрузчиком по умолчанию" и завоёвывает всё большую популярность у пользователей других операционных систем. Оправдывает, одним словом, свой титул. И это не только моё мнение.
Кроме уже названного соответствия спецификации мультизагрузки, вот неполный перечень возможностей GRUB:
* дружественность основных функций к пользователю;
* высокая функциональность в интересах разработчиков ядер;
* обратная совместимость для загрузки FreeBSD, NetBSD, OpenBSD и Linux;
* загрузка DOS, Windows NT и OS/2 методом "по цепи";
* множество загружаемых форматов;
* текстовый файл конфигурации;
* меню-интерфейс;
* гибкий командный интерфейс;
* множество поддерживаемых файловых систем;
* автоматическая декомпрессия;
* способность читать данные с любого из определяемых BIOS устройств;
* независимость от геометрии дисков;
* поддержка LBA;
* поддержка загрузки по сети;
* возможность работы с удалёнными терминалами.
Споры между приверженцами LILO и GRUB мало напоминают "религиозные войны", склонность к которым, к сожалению, иногда демонстрирует UNIX-сообщество. Возможно потому, что "пристрастный" анализ практически неминуемо убеждает, что GRUB превосходит соперника. Оставим в стороне функции, которых нет у LILO, но есть у GRUB: в конце концов, может вам никогда и не требовалось работать с удалёнными терминалами или загружаться исключительно с дискеты (по причине невозможности загрузки с HDD или CD-ROM). Сравним, как эти загрузчики выполняют только одну, общую для них функцию. Причём - основную: собственно загрузку ядер ОС.
Любой из загрузчиков при инсталляции "перехватывает инициативу", записывая начальную порцию своего кода (всё те же 512 байт - больше BIOS просто не прочитает) в главную загрузочную запись устройства. В этом смысле все они одинаковы: другого способа получить управление от BIOS не существует. Эта начальная порция кода в терминологии GRUB называется stage1. Трудно, однако, в 512 байтах (даже, меньше, как мы уже выяснили) разместить код, способный загружать разные ядра или даже ОС, да ещё и в меню-ориентированном режиме. Ближе всех к этому был Илья Евсеев, предложивший код главного загрузчика, способный загружать любой из загрузчиков трёх первичных разделов. Здорово, но при чём тут ядра Linux, BSD и прочая? Чай не DOS... Да и почему ограничиваться только первичными разделами?... "Патовая" ситуация разрешается загрузкой второй порции загрузчика. Вот тут-то и начинаются различия. Где BIOS находит код первой фазы загрузки (для GRUB - stage1) - известно: 0:0:0, как и договаривались, а вот где, в свою очередь, эта первая фаза будет искать своё продолжение (для GRUB - stage2, то есть)? LILO поступает просто: первая часть кода при инсталляции получает адрес продолжения в виде списка блоков, в которых и записано это самое "продолжение". "Продолжение" - не обязательно код. Это может быть и список необходимых файлов, но адресуемых физически, как блоки. GRUB же поступает изощрённее: в блоки, следующие за загрузочным, последовательно записывается код промежуточной фазы: stage1_5. Одного взгляда на имена файлов, содержащих инструкции этой фазы (все, оканчивающиеся на stage1_5) достаточно, что бы предположить её назначение: читать последующие данные средствами, предоставляемыми файловыми системами. И это предположение - верно. А вот что из этого следует:
* реконфигурация загрузчика не требует перезаписи главной загрузочной записи;
* предназначенные для загрузки ядра адресуются обычным для файловых систем способом;
* физические операции над содержимым диска (дефрагментация, перенос файлов), никак не отражаются на работе загрузчика;
* плюс следствие: логическая адресация объектов загрузки делает возможным управление ими не только по заранее определённому сценарию, но и в интерактивном режиме. И возможность эта реализована в виде командного режима работы.
Выше изложенного уже достаточно, что бы предпочесть GRUB. При этом не надо думать, что адресация посредством физических блоков не известна GRUB. Если запись stage1_5 по каким-либо причинам невозможна, то применяется адресация посредством физических блоков. То есть, в этом случае GRUB как бы "опускается" до методологии LILO. Надеюсь, убедил. Перейдём к конкретным деталям.
Как сделать
Если не обнаружено в дистрибутиве (что, в настоящее время, уже маловероятно), то на ftp://alpha.gnu.org/gnu/grub/ можно обнаружить следующие файлы:
* grub-VERSION.tar.gz
* grub-VERSION-i386-pc.ext2fs
* grub-VERSION-i386-pc.tar.gz
Первый из перечисленных - привычный tarball, предназначенный для распространения в исходных текстах. Из его содержимого GRUB можно бесхитростно построить:
$ ./configure
$ make
$ make install
В результате получится так называемая host-версия загрузчика - почти полнофункциональная, но запускаемая не BIOS, после обнаружения в загрузочном блоке, а как обычное приложение.
Второй - образ дискеты с файловой системой ext2. Загрузившись с этой дискеты, получаем возможность работы с полнофункциональным, системно независимым вариантом загрузчика.
Третий - бинарный вариант распространения, содержащий все необходимые файлы. Редкий случай: даже последовательные сторонники самостоятельной компиляции ПО, признают, что использование предлагаемых бинарных файлов вполне оправдано: самостоятельная компиляция ничего не добавит, поскольку процесс определяется архитектурой IBM PC и особенностями различных файловых систем. Отсутствует только host-версия. Но при наличии дискеты, загружающей GRUB, без неё вполне можно обойтись.
Способов инсталляции загрузчика несколько и, как мне кажется, проще разобраться в сути происходящего, нежели их запомнить. Действительно необходимыми являются только две вещи: каталог /boot/grub/ (с содержимым: stage1, stage2 и stage1_5 для интересующих файловых систем) и наличие stage1 и stage1_5 в начальных блоках устройства. Разумеется, stage1_5 должна соответствовать файловой системе, на которой расположен каталог /boot/grub/.
С созданием каталога /boot/grub/ проблем вообще никаких быть не может, а вот способов поместить stage1 и stage1_5 в начальные блоки действительно несколько. И хотя применение команды dd, своей мощностью, простотой и, одновременно, опасностью напоминающей лом, против которого, как известно, "нет приёма", не возбраняется, в данном случае рекомендуется всё-таки пользоваться средствами GRUB. Сойдёт и host-версия, и загруженная с оригинальной дискеты. В любом случае достаточно набрать команды:
grub> root (fd0)
grub> setup (fd0)
Разумеется, вместо (fd0) может быть любое другое блочное устройство. Вообще setup - скрипт, включающий в себя несколько команд более низкого уровня (install, embed, etc...), но коль уж он существует, почему бы им не воспользоваться? Нужно только помнить, что:
* идентификатор устройства или раздела всегда "обрамляется" круглыми скобками;
* нумерация устройств и разделов начинается с нуля;
* логические разделы HDD имеют номера, начиная с 4 (что для пользователей UNIX не должно быть удивительным).
Полный формат идентификатора выглядит так:
(device[,part-num][,bsd-subpart-letter])
где device - имя устройства, part-num - номер раздела, bsd-subpart-letter - буквенный идентификатор подраздела, известный, очевидно, пользователям BSD.
Что умеет
Умеет GRUB много. С точки зрения некоторых пользователей - даже слишком. Количество используемых команд существенно превышает пол сотни. В документации они разделены на меню-специфичные, используемые только в глобальной секции конфигурационного файла, общие, используемые как в описании меню, так и в командном режиме, и команды интерактивного режима, которые если и могут быть включены в конфигурационный файл, то только в секциях, описывающих отдельные позиции меню. Повторение описания - занятие неблагодарное. GRUB прекрасно документирован: распространяемый пакет включает в себя небольшой man и исчерпывающее info. С соответствующей странички сайта GNU можно скачать документацию в html-формате. Но, возможно, ничего этого делать и не придётся: GRUB имеет встроенную систему помощи, которая в ответ на <help> всегда выведет список доступных к выполнению команд, а в ответ на <help command> выдаст дополнительную информацию. Автозаполнение строки подскажет не только синтаксис команды, но и, в некоторых случаях, варианты её продолжения (доступные устройства, разделы). Одним словом, эпитет bash-подобной командная оболочка GRUB имеет вполне заслуженно. При всём этом как-то даже неловко повторяться... Последовав примеру Daniel Robbins, просто приведём конфигурационный файл, включающий в себя наиболее часто используемые команды:
default 0
timeout 30
color light-gray/blue black/light-gray
title=Boot Linux
root (hd0,4)
kernel /boot/bzImage ro root=/dev/hda5 vga=792 hdd=ide-scsi
title=Boot Linux using initrd
root (hd0,5)
kernel /boot/bzImage root=/dev/loop0 vga=791 init=/initdisk.gz
initrd /initdisk.gz
title=Windows NT
root (hd0,3)
chainloader +1
Параметры ядру передаются, очевидно, обычным образом. Разумеется, значение параметра root описывает корневой раздел в нотации Linux, а не GRUB, а, в остальном, мне кажется, ошибиться довольно трудно.
Все "горячие" клавиши, действующие при появлении меню на экране, описаны в нижней части самого же меню. В командном режиме <help> к вашим услугам: авторы, кажется, сделали всё, что бы избавить склонных к графомании от стремления описывать их детище, за что им особое спасибо.
Приведём только функции, предназначенные для создания различных вариантов загрузки. Найти соответствующие команды труда не составит.
* создание новых первичных разделов;
* изменение типов разделов;
* изменение флагов активности (загружаемости) первичных разделов;
* "скрытие" разделов прибавлением 0x80 к их идентификатору;
* map-ирование устройств: подмена одного блочного устройства другим, как это делает BIOS, для того, что бы осуществить загрузку не с первого винчестера, например.
А вот файловые операции, облегчающие работу в командном режиме:
* получение списка блоков файла, как раз для того случая, когда stage1_5 для используемой файловой системы не существует;
* просмотр содержимого файла. Очень полезно. Например:
grub> cat /etc/fstab
* сравнение файлов;
* поиск файла;
* загрузка ядра и модулей.
И ещё...
В заключение, перечислим функции, расширяющие возможности загрузчика. Возможно, использует их лишь небольшая часть пользователей, но упоминания они всё же заслуживают. Итак...
* вывод меню в графическом режиме, на фоне, определяемом так называемым splashimage;
* загрузка по сети при наличии tftp-сервера. То есть, сервер присваивает клиенту ip-адрес, после чего становится возможной загрузка конфигурационного файла или ядра непосредственно с сервера. Возможно и ручное конфигурирование сетевого интерфейса;
* защита паролем меню или его отдельных позиций. Пароль может шифроваться;
* скрытие меню. Загрузка в этом случае произойдёт в соответствии с позицией меню "по умолчанию", если только тайм-аут не будет прерван нажатием <Esc>;
* загрузка вычислительных систем, не снабжённых клавиатурой и дисплеем. В этом случае используется последовательный интерфейс;
* возможность протестировать адекватность чтения файловой системы до загрузки ядра;
* возможность переназначения клавиш.