Знакомимся с RIP - делаем свой Live CD
Владимир Попов
🕛 28.02.2007, 13:42
Зачем?Вряд ли в настоящее время требуется объяснять, что такое Live CD. CD-диск (или flash-накопитель, что в данном случае не имеет принципиального значения), несущий на себе "самодостаточную" ОС, неоднократно признавался специалистами в сфере программного обеспечения одним из наиболее примечательных решений последнего десятилетия. "Спасательные" (rescue) системы, инсталляционные диски дистрибутивов, демо-версии ОС и отдельных приложений, "целевые" (обеспечивающие решение определённого круга задач) системы - все они, по сути, представляют собой Live CD.
Подобное разнообразие сначала приводит к вопросу: "И как же это делается?", - а затем и к размышлениям: "А не создать ли мне свой собственный Live CD?". Если вы профессионально занимаетесь обслуживанием вычислительных систем, то потребность в собственном Live CD почти наверняка есть. Аналогично, если вам часто случается проводить демонстрации на "чужих" компьютерах, то история создателя Knoppix Клауса Кноппера (Klaus Knopper) может показаться интересной. Одним словом, тема представляется достойной обсуждения.
Есть два основных способа научиться что-то делать: получить фундаментальные знания и только потом перейти к практике или идти от прототипа, осваивая знания и навыки одновременно, изучая прототип и создавая собственную "версию". Нет смысла спорить об эффективности обоих способов, но "веселее" всё-таки второй. По крайней мере, если поставленная цель - создание собственного Live CD.
Почему - RIP?
По данным Distrowatch.com, на настоящий момент известно 224 Live CD, из которых 176 - активно поддерживаются. Который выбрать в качестве прототипа для собственной разработки? Как сказал один пролетарский поэт: "делать жизнь - с кого?" Я бы рекомендовал RIP Кента Роботти (Kent Robotti). Вопреки мрачноватому названию ("R.I.P" - традиционная надпись на надгробьях в англоязычных странах, представляющая собой аббревиатуру печальной фразы "Rest In Peace" - "покойся с миром"), назначение этого Live CD исключительно оптимистично, а название означает ни много, ни мало "Recovery Is Possible", то есть: "Восстановление - возможно!".
В актив RIP можно занести следующее:
компактность: iso-образ в 32 MB - совсем не много по нынешним временам;
современность, которая отчасти предопределена компактностью: поддерживать актуальность ядра, библиотек и утилит для дистрибутива с сотней приложений намного проще, чем для дистрибутива, количество приложений в составе которого "перевалило" за две тысячи;
рациональность: RIP быстр, независим от привода CD после загрузки и полезен, поскольку сохранность данных - проблема общая и для программиста, и для дизайнера, и для бухгалтера.
Ещё одно обстоятельство, свидетельствующее в пользу RIP - личность хранителя. Кент Роботти известен как автор многих патчей и нескольких программ: pkgtool2, make_uninstall, mnsetup, grubconfig, backup-mbr. Приведенный список однозначно говорит о том, что автор хорошо ориентируется в различных Linux-дистрибутивах (pkgtool2/make_uninstall предлагают универсальный способ инсталляции приложений и конвертации tgz/rpm/deb), сведущ в коммуникациях (mnsetup автоматизирует установку ПО, необходимого для организации mail и news), занимался вопросами загрузки (grubconfig) и не "понаслышке" знаком с проблемами потери информации на HDD (backup-mbr).
Мне, во всяком случае, всегда было интересно знакомиться со взглядами Кента на текущие возможности ядра и алгоритм загрузки, список "первоочередных" утилит и средства восстановления файловых систем. До сих пор разочарован я не был ни разу. Поэтому и предлагаю, вслед за Кентом Роботти, быстродействие предпочесть универсальности, а компактность - красотам графической среды.
Принципы
Более десяти лет прошло с тех пор, как с "лёгкой руки" Вернера Алмсбергера (Werner Almesberger) и Ганса Лермена (Hans Lermen) в коде ядра Linux-1.3.73 появилось устройство initrd (initial RAM disk). Потребность в последнем объяснялась просто: корневая файловая система Linux может располагаться, грубо говоря, "чёрт-те где". Помимо само собой разумеющихся HDD и FDD, это могут быть SCSI, Zip и CD-ROM накопители, сетевые ресурсы и т.д. и т.п. Что же, ядро должно изначально поддерживать все эти устройства? Накладно, но возможно. А как быть, если монтированию корневой файловой системы обязательно предшествуют операции настройки (сетевые, например)? Вместо усложнения ядра было предложено снабжать его "начальной файловой системой в памяти". В конце концов, если ядро как-то попало в память (от тонкостей аппаратной реализации загрузки абстрагируемся), то почему бы тем же способом в память не загрузить файловую систему, содержащую всё необходимое для монтирования уже "настоящей" файловой системы?
Практически, initrd загружается в память загрузчиком и "видится" ядром как устройство /dev/initrd. Устройство это блочное, то есть "в первом приближении" - диск, который можно монтировать, что, собственно, ядро и делает, оказавшись в памяти (загрузка initrd всегда предшествует загрузке ядра, хотя конфигурационные файлы загрузчиков и намекают на обратный порядок). Далее ядро декомпрессирует (разархивирует) содержимое этого смонтированного диска и переносит его на устройство /dev/ram0 (или /dev/rd/0 при использовании devfs, о чём, похоже, в настоящее время можно уже забыть). Именно /dev/ram0 и становится корневой файловой системой (по крайней мере, в первой фазе загрузки) при использовании initrd.
Стандартное использование initrd предполагает на следующем этапе выполнение файла /linuxrc, в функции которого входит прежде всего загрузка модулей, необходимых для обеспечения доступа к "настоящей" корневой файловой системе (на устройствах SCSI, SATA, NFS и т.п), операции настройки, если требуется, и, наконец, монтирование этой самой "настоящей" корневой файловой системы. В отсутствие файла /linuxrc ядро запустит /sbin/init, как это происходит в случае загрузки без initrd. Корневой файловой системой в этом случае останется /dev/ram0.
Сообразительный читатель уже, вероятно, догадался, что если initrd будет содержать всё необходимое для работы системы (в том числе и /sbin/init, разумеется), а загрузка будет происходить с CD-ROM, то первая фаза загрузки при стандартном использовании initrd, представляет собой ничто иное, как загрузку Live CD. Вот так внедрение initrd "между делом" обеспечило возможность существования систем, корневая файловая система которых (полностью или частично) расположена в памяти.
О том, что корневая файловая система всех Live CD располагается в памяти, все уже и так догадались: где же ещё можно обеспечить возможность записи, если в вашем распоряжении только read-only CD? Другое дело, что объём памяти вычислительной системы (а значит, и объём /dev/ram0) может не соответствовать пожеланиям к количеству и составу доступных для запуска приложений. Тогда придётся вспомнить, что, во-первых, целый ряд каталогов корневой файловой системы совершенно не нуждаются в возможности записи в них, а во-вторых, монтировать можно не только к каталогам /mnt/* или /media/*.
Ничто не мешает иметь в initrd "пустыми" такие традиционно объёмистые каталоги, как /opt или /ust/X11R6, чтобы потом монтировать к ним нужные файловые системы. Беда в том, что файловая система CD (iso9660) не всегда удовлетворяет требованиям, предъявляемым к тем же /opt или /ust/X11R6 (ограничения на формат имён файлов, отсутствие необходимых атрибутов и т.п.), но и это преодолимо, если вспомнить о существовании таких замечательных устройств, как /dev/loopN. Для каталога /opt, например, определите нужный размер: du -sh opt
создайте файл в соответствии с определённым размером (X - размер в килобайтах): dd if=/dev/zero of=opt.img bs=Xk count=1 mke2fs -F -m0 -b 1024 opt.img
монтируйте его, как loopback-устройство: mount opt.img /mnt/image -o loop
Перенесите в /mnt/image содержимое /opt и после демонтирования в вашем распоряжении файл opt.img, которым можно воспользоваться уже при работе с файловой системой Live CD. Просто монтируйте его к каталогу /opt: mount /mnt/cdrom/img/opt.img /opt -o loop
Каталог /opt, таким образом, принадлежит файловой системе на /dev/ram0, а вот содержимое его находится на CD, в файле cdrom/img/opt.img.
Воспользовавшись возможностями файловой системы cramfs (compressed ram file system) из состава канонического ядра или cloop (compressed loop), как это сделано в Knoppix, файлы-образы каталогов можно ещё и компрессировать. Именно так и получается, что 700MB-ный CD предлагает 2GB программного обеспечения.
Вопрос заключается в том, нужно ли это при создании собственного Live CD. Кент Роботти, например, считает это излишним: то, что является необходимостью для demo-CD, для rescue-систем совсем не обязательно. Не обязательно это и для многих целевых систем: Movix и GeexBox, например, представляющие собой, фактически, мультимедийные центры, также полностью размещаются в памяти. Не будем и мы углубляться в проблемы Live CD, обращающихся к CD-приводу во время своей работы.
Для того, чтобы ядро Live CD "вписывалось" в представленную выше схему загрузки, оно должно поддерживать разделяемые области памяти, RAM-диски, initrd, файловые системы proc и tmpfs и ту файловую систему, на которой создавался initrd - не обременительные, в общем-то, требования.
Коснувшись ядра, перейдём к такой его важнейшей функции, как поддержка оборудования. Определение оборудования не является задачей, сколько-нибудь специфичной для Live CD. Современное "дистрибутивостроение", повсеместно отказываясь от devfs, а вслед за ним и от hotplug, всё чаще предлагает пользователю воспользоваться ядром с "универсальным", сравнительно полным набором модулей драйверов, дополнив его, в крайнем случае, initrd. Это стало возможным после того, как ISA-устройства вышли из употребления, а вместе с ними отпала нужда и в модулях, способных конфликтовать при попытке обращения к одним и тем же аппаратным ресурсам.
Кроме того, пренебречь наличием в памяти ненужного 50-ти килобайтного модуля значительно проще, если этой памяти не 16MB, как бывало, а 256, что в настоящее время является нормой. Фактически, планируя собственный Live CD, выбирать приходится между двумя возможностями:
использовать доступный определитель оборудования (kudzu из RedHat, hwdetect из Arch Linux, hwsetup из Knoppix и т.п.);
не определять оборудование вообще, положившись на ядро, включающее в себя большую часть драйверов.
Что-то мне подсказывает, что большинство предпочтёт второй вариант, хотя, возможно, я и ошибаюсь.
Последним "фундаментальным" вопросом является загрузка Live CD. Если пользователи MS Windows, как правило, плохо представляют, как это происходит, то о линуксоидах, обычно, так сказать нельзя. Конфигурационные файлы LILO и Grub вполне читабельны и рано или поздно пользователь Linux узнаёт, что BIOS сначала загружает в память и запускает на выполнение загрузчик, который, в свою очередь, загружает ядро ОС и, возможно, initrd. Тот же загрузчик передаёт ядру параметры, один из которых имеет незатейливое имя root и указывает на местоположение корневой файловой системы. Загрузка Live CD отличается лишь несколькими моментами:
в качестве загрузчика используются isolinux или grub, но не LILO;
применение initrd обязательно, поскольку, как мы выяснили, "initial RAM disk" и является, собственно, корневой файловой системой;
из чего следует, что параметр загрузки root должен указывать на /dev/ram0.
Отказ от LILO понятен: этот загрузчик не предназначен для использования с CD. isolinux, напротив, именно для этого придуман и долгое время был единственным загрузчиком, использовавшимся при создании Live CD. Начиная с версии 0.95, для загрузки с CD стало возможным использовать Grub. Принимая во внимание универсальность этого загрузчика, именно его бы я и предпочёл, но у isolinux есть одна сильная черта - возможность иметь несколько help-файлов (по числу F-клавиш). В остальном оба упомянутых загрузчика равноценны (только в отношении загрузки с CD, разумеется: в широком смысле Grub как загрузчик не имеет себе равных).
Реализация
Ознакомившись с изложенными выше принципами, можно перейти непосредственно к RIP и посмотреть, как они реализованы в данном случае. Начнём с initrd, представляющего собой компрессированный образ корневой файловой системы. Не вдаваясь в детали и следуя рекомендациям Кента, выполните следующие команды: mkdir livecd_root cd livecd_root gzip -dc ../rootfs.cgz | cpio -iumdv
Предполагается, что каталог, в котором планируется развернуть корневую файловую систему RIP, будет называться livecd_root, а сам файл rootfs.cgz находится уровнем выше. Понятно, надеюсь, что команда gzip просто разархивирует rootfs.cgz, а команда cpio превращает полученный файл-образ в дерево каталогов.
В полученном дереве каталогов без труда угадывается Slackware, впрочем, Кент и сам говорит об этом. Хорошо, что Slackware, а не SuSe или Debian, потому что модификация Slackware потребует от пользователя только знания принципов, по которым загружаются все BSD-системы. /etc/inittab адресует нас к /etc/rc.d/rc.S и /etc/rc.d/rc.M, а всю дальнейшую информацию можно получить просматривая эти файлы: спасибо Патрику (Patrick Wolkerding - автор Slackware) за исчерпывающие комментарии, спасибо Кенту за его выбор.
Для осуществления обратной операции (создания компрессированного образа из дерева каталогов) выполните команды: cd livecd_root find . | bin/cpio -v -o -H newc | gzip -9 >../rootfs.cgz
Использование find вызвано тем, что для архивирования образа, cpio нужно использовать не тот, что имеется в вашей системе, а тот, который входит в состав RIP.
Как компилировалось ядро из состава RIP, можно узнать, познакомившись с содержимым файла kernel.txt. Отметить можно следующее:
ядро предполагает поддержку CPU, известных как "generic x86";
не поддерживаются Software Suspend, APM и CPU Frequency scaling (управление частотой CPU), но поддерживается ACPI;
не поддерживаются PCI Express и PCI Hotplug, но поддерживаются ISA и PCMCIA/CardBus;
поддерживаются сокеты unix и TCP/IP, но не поддерживаются IrDA, Bluetooth и Wi-Fi;
поддерживаются практически все известные ядру 10, 100 и 1000 Mbit сетевые адаптеры;
поддерживаются практически все блочные устройства (IDE, включая SATA, SCSI, RAID и LVM, FireWire);
не поддерживаются ISDN, Sound, Hardware Monitoring и Multimedia devices;
поддерживаются порт PS/2 и мышь, но не поддерживаются Touchscreens и Joysticks;
поддерживаются практически все известные ядру файловые системы;
поддерживается USB.
На мой взгляд, приведенный список как раз и соответствует задачам, которые предстоит решать rescue-cd. Если же ваши потребности существенно отличаются, то ничто не мешает использовать в составе Live CD своё собственное ядро.
При сборке ядра Кент полностью отказался от загружаемых модулей: ядро при этом "выросло" до 3-х мегабайт, зато отпала необходимость в определении оборудования и, соответственно, подзагрузке модулей. Решение, быть может, не оптимальное, но для Live CD, на мой взгляд, вполне приемлемое.
Осталось выяснить, как это всё загружается. ISO-образы RIP, которые можно взять на http://www.tux.org/pub/people/kent-robotti/looplinux/rip/ используют в Grub, хотя ещё совсем недавно в качестве загрузчика использовался isolinux. В настоящее время в состав RIP входят и Grub, и isolinux, а скрипт mkiso.sh создаёт iso-образ с использованием того загрузчика, который указан в качестве первого параметра. Для создания собственного Live CD создайте каталог, содержащий подкаталог boot, а в нём - подкаталог grub. В подкаталог boot поместите файлы kernel и rootfs.cgz, в подкаталог grub - файлы из одноимённого подкаталога исходного диска RIP. Если имя созданного каталога rip-iso, то запуск mkiso.sh, в каталоге уровнем выше rip-iso выполните так: sh mkiso.sh grub rip-iso . rip_grub.iso
В результате файл rip_grub.iso будет создан в текущем каталоге.
Для isolinux вместо подкаталога grub в boot создайте подкаталог isolinux. Разумеется, первым параметром для mkiso.sh в данном случае также будет "isolinux", а имя создаваемого файла логично будет изменить на rip_isolinux.iso.
Запись диска можно осуществить любым доступным способом, а при желании, даже непосредственно из RIP, поскольку последний содержит и mkisofs, и cdrecord (и dvdrecord с cdrwtool, впридачу).
Практикум
Какие же изменения стоит внести в оригинальный RIP, чтобы он в большей мере соответствовал вашим потребностям?
Любителям использовать мышь можно рекомендовать "включить" gpm. Для этого, в соответствии с правилами Slackware, файл /etc/rc.d/rc.gpm сделайте исполняемым: chmod +x etc/rc.d/rc.gpm
Предполагается, что команда издаётся в созданном нами каталоге livecd_root. Поскольку rc.gpm ссылается на /dev/mouse, то в каталоге /dev создайте символическую ссылку: ln -s input/mouse0 mouse
Исполняемым также стоит сделать файл /etc/rc.d/rc.font - это даст возможность после загрузки фонта с кириллицей читать на родном языке. Фонт, разумеется, также можно установить свой. Для этого перепишите в каталог /usr/share/kbd/consolefonts/ свой любимый консольный фонт (рекомендую terminus), и внесите соответствующие изменения в /etc/rc.d/rc.font. Например: setfont -v ter-k16f -m koi8-r_to_uni
При наличии кириллицы, файл /etc/issue имеет смысл заменить на свой собственный. Содержимое этого файла выводится перед приглашением "login".
Приверженцам Midnight Commander можно посоветовать сохранить файл ~/.mc/ini в каталоге /root/.mc/. Тогда mc в соcтаве RIP унаследует ваши личные настройки.
Если предполагается использовать Live CD для подключения к удалённым NFS или SMB ресурсам, не забудьте загрузить portmap (сделайте исполняемым /etc/rc.d/rc.portmap). Всем, кто не очень знаком со Slackware, вообще стоит изучить содержимое каталога /etc/rc.d/ - скрипты Патрика отлично прокомментированы и вы, возможно, узнаете из них нечто полезное.
Существенно изменит RIP замена ядра системы на своё собственное. Мне, например, кажется не лишним включение поддержки framebuffer (CONFIG_FB=y), драйвера vesa (CONFIG_FB_VESA=y) и возможности переключения видеорежимов (CONFIG_VIDEO_SELECT=y), поскольку консоль vga (640х480) на 17..19 дюймовых LCD мониторах выглядит изрядным анахронизмом.
Обратите внимание, что, отказавшись от ядра Кента Роботти в пользу канонического, вы лишитесь поддержки некоторых контроллеров PATA, REISER4 и SQUASHFS, поскольку эти опции - результат наложения независимых патчей. Впрочем, это относится только к RIP-0.15 и ядру 2.6.16 - для другой версии и другого ядра отличия могут быть иными.
Разумеется, вы можете инсталлировать в RIP пакеты Slackware. В общем - делать всё, что вы обычно делаете со своей "основной" системой. Проверить работоспособность добавленного приложения можно, даже не переписывая Live CD. Выполните chroot livecd_root
и вашей корневой файловой системой (вплоть до exit) станет файловая система будущего Live CD.
И немного об использовании...
В заключение, несколько реверансов в адрес Кента Роботти, которые, быть может, обратят ваше внимание на содержимое RIP.
Нет смысла, как ни странно, обсуждать средства восстановления данных из состава RIP - тема достойна отдельного разговора. Ограничимся констатацией факта, что список этот достаточно полон, всегда в актуальном состоянии и не ограничивается миром Linux, вплоть до утилит модификации ntfs-разделов и изменения паролей CMOS/BIOS и Windows NT/XP SAM.
Последняя версия пакета ntfsprog обеспечит монтирование с возможностью записи разделов ntfs, утилита ntfsresize, как вы уже догадались, позволит безопасно менять размеры таких разделов, а ntfsclone попытается создавать их копии (вопреки утверждению MicroSoft о невозможности подобной операции). Одним словом, интересующимся восстановлением данных стоит познакомиться с опытом Кента.
Несколько слов по поводу Grub. Мало того, что Кент Роботти всегда использует самую современную версию этого загрузчика, так она у него ещё и "усилена" возможностью чтения с разделов Reiser4 и NTFS, дополнена утилитами использования под DOS/Windows и конфигуратором собственного производства.
Не оставлены без внимания и ldlinux/isolinux: скрипт и подробные инструкции по поводу того, как создать RIP на usb-накопителе - к вашим услугам.
Особого упоминания заслуживает документация в составе RIP. Написанного собственно Кентом не так и много, но содержимое каталога rootfs/usr/doc прекрасно дополняет комплект man, который также присутствует в RIP. Именно так: 30-ти мегабайтный RIP включает в себя man-ы всех используемых программ плюс документацию в формате plain text для тех случаев, когда man приложения отсутствует или недостаточен. Известная фраза "Изучая Debian, ты изучаешь Debian. Изучая Slackware, ты изучаешь Linux", как нельзя лучше подходит к RIP, документация которого - маленькая энциклопедия Linux.
Что касается ядра в составе RIP, то оно хоть и не "на все случаи жизни", но может быть очень полезным. Как определяет конфигурацию вашего оборудования последняя стабильная версия? Не появилась ли в ядре поддержка адаптера, которой вы уже давно ждёте? Не улучшилась ли поддержка SATA-винчестеров? Воспользовавшись последней версией RIP и возможностями sysfs, всё это можно выяснить, не прибегая к сборке нового ядра. Для кого-то это может быть заманчивым...