Sources.RU Magazine Поиск по журналу
 

TopList

Linux Live CD - Основы

Автор: RaD

По материалам забугорного сайта

Введение

Зачем помещать Linux на загрузочный CD? Такое решение позволяет иметь Linux на практически любом компьютере, не теряя времени на его установку и настройку. Ярким примером является дистрибутив Blin Linux 1.3, который позволяет смотреть видео на компьютере и требует наличия 64 MB RAM и CD-драйва. Винт ему не требуется, да и CD-драйв освобождается сразу после загрузки системы. Удобно!

Данная статья описывает создание "основы" для дистрибутива подобного рода, который в дальнейшем можно усовершенствовать до нужного вам состояния.

Стандартом для загрузочного CD является El Torito, смысл которого заключается в том, что BIOS считает CD-драйв дисководом и ищет на нём загрузочный образ. Но есть альтернатива в виде ISOLINUX, данное решение не использует эмуляции дисковода и позволяет работать со всем CD-диском.

Процесс загрузки

Стандартный процесс загрузки Linux выглядит как-то так:

  • Компьютер запускает LILO или подобный загрузчик.
  • LILO знает где находится ядро и запускает его.
  • Запускается ядро, после проведения стандартных тестов, оно монтирует корневую файловую систему.
  • После этого запускается /sbin/init и операционная система запускается в соответствии с /etc/inittab и скриптами rc.d.

Процесс загрузки с CD немного отличается. Нам снова нужен загрузчик, но необязательно знать, каким устройством является наш CD-драйв. Он может быть /dev/hdb, /dev/hdc или /dev/hdd. Даже если мы скажем загрузчику, где находится ядро, нам надо будет указать ядру где находится корневая файловая система. В поиске CD-драйва нам помогает ISOLINUX, но не решает проблемы с поиском корневой файловой системы. Многие загрузочные диски используют так называемый initrd (initial ram disk), который является диском в оперативной памяти с минимальной корневой файловой системой. Идея заключается в том, что ядро загружает минимальную файловую систему, на которой находятся модули, которые позволяют найти и подгрузить основную корневую файловую систему. Теперь рассмотрим процесс загрузки Linux с CD:

  • Загрузка с CD с ISOLINUX.
  • ISOLINUX загружает ядро из каталога /isolinux на CD-диске.
  • Затем ISOLINUX загружает initrd.gz, сжатую ext2 файловую систему.
    Важно понимать, что initrd.gz загружается не ядром!
  • Ядро запускается и разжимает initrd.gz в память (обычно в /dev/ram0) и монтирует его в корень.
    Ядро должно быть собрано с опциями поддержки initrd и ramdisk.
  • Ядро пытается запустить linuxrc в новой файловой системе.
  • Программа linuxrc в свою очередь пытается примонтировать CD-диск, а затем копирует сжатую основную файловую систему в память (обычно в /dev/ram1). Новая файловая система монтируется и в её каталоге /dev создается символическая ссылка на CD-драйв.
  • После завершения работы linuxrc, управление возвращается ядру и оно пытается примонтировать свою сконфигурированную файловую систему. В данном случае, с помощью команды rdev указываем ядру использовать /dev/ram1 в качестве корневой файловой системы, в которой есть /sbin/init и система стартует прямо из памяти.
Но зачем надо разбивать процесс загрузки на две фазы? Дело в том, что Linux не знает как грузиться с CD. Преимущество наличия первой фазы загрузки состоит в том, что файловая система initrd загружается загрузчиком, а не ядром. Это означает, что мы сможем загрузиться с любого устройства, с которого сможет запуститься загрузчик.

Создание ядра

Теперь необходимо создать ядро, которое сможет загружать initrd файловую систему. Процесс сборки ядра опищем позднее, а пока предположим, что вы умеете это делать :) Ядро должно быть собрано с поддержкой initrd и RAM дисков. Будем использовать размер RAM диска по умолчанию, т.е. 4 MB. Также следует подключить поддержку файловых систем ISO9660 и EXT2. После сборки ядра его необходимо настроить на использование конкретного корневого устройства.

Допустим, вы только что выполнили команду make bzImage
rdev /usr/src/linux/arch/i386/boot/bzImage /dev/ram1
Если у вас нет устройства /dev/ram1, то его следует создать
mknod -m 640 /dev/ram1 b 1 1

Создание дерева каталогов

Создадим шаблон для нашего дистрибутива.

Ключевые каталоги:
  • cdimage/ — этот каталог будет записываться на CD.
  • initrd/ — этот каталог содержит файловую систему initrd.
  • root/ — этот каталог содержит рабочую файловую систему.

Настройка initrd

Фаза INITRD имеет простую цель — получить рабочую файловую систему в /dev/ram1. Есть несколько способов сделать это. Перечислим их попорядку:

  • Использовать небольшой shell скрипт (ash) для монтирования CD, разворачивания (gunzip) файла rootfs.gz в /dev/ram1. Такой подход требует наличия libc, что увеличивает размер initrd.gz до 600 KB. Это самый прямой подход. [ссылка]
  • Использовать программу linuxrc написанную на i386 ассемблере выполняющую аналогичные действия, за исключением использования другого алгоритма компрессии, т.к. gunzip слишком сложен для его реализации на ассемблере. Программа будет "весить" всего 1 KB и не требовать наличия дополнительных библиотек. Файл initrd.gz будет иметь размер около 10 KB. [ссылка]
  • Использовать программу linuxrc написанную на C и статически слинкованную, которая использует для декомпрессии gunzip.c, и успешно выполняет задачи shell скрипта. Будучи статически слинкованной с библиотекой dietlibc, программа будет занимать меньше места, чем в случае динамической линковки с libc-2.1.3. Программа будет "весить" примерно 20 KB, а размер файла initrd.gz будет 15 KB. [ссылка]
Программа на C является оптимальным выбором, т.к. имеет небольшой размер и использует "стандартный" метод декомпрессии.

Перечислим основные этапы выполняемые программой:
  • Монтирование /proc.
  • Открываем файл /proc/ide/ide0/hda/media, если там написано "cdrom", то значит мы нашли наш CD (хм, а если у меня в машине несколько CD-драйвов???). В противном случае проверяем /proc/ide/ide0/hdb/media, /proc/ide/ide1/hdc/media и /proc/ide/ide1/hdd/media пока не встретится первый CD-драйв (о как!). То есть, грузиться мы можем только с этих четырех IDE CD-драйвов!
  • Переходим в каталог /dev и создаём символическую ссылку cdrom на найденное устройство.
  • Монтируем CD-драйв в каталог /cdrom.
  • Открываем /cdrom/rootfs.gz и разворачиваем его в /dev/ram1. В rootfs.gz должна находиться EXT2 файловая система размером в 4 MB.
  • Монтируем /dev/ram1 в /ram.
  • Переходим в каталог /ram/dev и создаём символическую ссылку на устройство с CD-диском.
  • Размонтируем /ram, /cdrom и /proc.
После этого ядро должно приняться за работу и примонтировать /dev/ram1 как / и попытаться запустить /sbin/init.

Рабочая корневая файловая система

С одной файловой системой initrd многого не сделаешь. Необходимо создать полезную корневую файловую систему. А так как мы используем RAM диск объёма 4 MB, он немного сжатый. Почему бы не использовать RAM диск большего размера? Да просто незачем зря забивать память и надо помнить о пользователях компьютеров с небольшим объёмом оперативной памяти. Возмём библиотеки:
ld-2.1.3.so
ld-linux.so.2 -> ld-2.1.3.so
libbz2.so.1.0 -> libbz2.so.1.0.0
libbz2.so.1.0.0
libc-2.1.3.so
libc.so.6 -> libc-2.1.3.so
libcom_err.so.2 -> libcom_err.so.2.0
libcom_err.so.2.0
libdl-2.1.3.so
libdl.so.2 -> libdl-2.1.3.so
libe2p.so.2 -> libe2p.so.2.3
libe2p.so.2.3
libext2fs.so.2 -> libext2fs.so.2.4
libext2fs.so.2.4
libm-2.1.3.so
libm.so.6 -> libm-2.1.3.so
libncurses.so.5 -> libncurses.so.5.0
libncurses.so.5.0
libtermcap.so.2 -> libtermcap.so.2.0.8
libtermcap.so.2.0.8
libuuid.so.1 -> libuuid.so.1.2
libuuid.so.1.2


Не все из них нужны для старта операционной системы. В католеге /bin находятся необходимые утилиты. Также создан скрипт /sbin/init. В каталоге /etc находятся файлы inittab и termcap, а также каталог rc.d, в котором находится скрипт rc.S используемый для запуска операционной системы. Приведём ключевую часть файла inittab:

id:1:initdefault:
si::sysinit:/etc/rc.d/rc.S
c1:1235:respawn:/bin/sulogin /dev/tty1

Использование sulogin для консоли приводит к тому, что пользователь попадает в административный режим.

Файл /etc/fstab выглядит следующим образом:

/dev/ram1      /                ext2            defaults                     1   1
none               /dev/pts   devpts         gid=5,mode=620      0   0
none               /proc         proc            defaults                    0   0

Также присутствует пустой каталог /initrd, который указывает, что фаза INITRD завершена и рабочая корневая файловая система на /dev/ram1 примонтирована, файловая система initrd (находящаяся на /dev/ram0) удалена из /initrd. Это означает, что мы можем размонтировать её и освободить память используемую RAM диском.

Посмотрим внутренности скрипта rc.S:

#!/bin/sh
PATH=/bin; export PATH
echo "System init"
mount -t proc none /proc
mount -o remount,rw /
echo "Find the extras on the CD and mount it"
if [ -r /dev/cdrom ] ; then
    mount -t iso9660 /dev/cdrom /cdrom
    mount /dev/hda9 /a
fi
cd /
umount /initrd
freeramdisk /dev/ram0

Сначала мы монтируем /proc, а затем перемонтируем / в режиме записи (мы имеем правильную запись о / в /etc/fstab). Проверяем наличие устройства /dev/cdrom (оно должно было быть создано в фазе INITRD) и монтируем его. В рабочей файловой системе сделана символическая ссылка из /usr в /cdrom/usr. Таким образом, дополнительное программное обеспечение можно хранить в этом каталоге на CD-диске. В тестовых целях был примонтирован раздел жёсткого диска в каталог /a.

Создание CD

Теперь у нас есть ядро, структуры файловых систем initrd и rootfs. Как же их записать на CD-диск? Рассмотрим простейшую структуру каталогов на CD-диске:

/rootfs.gz
/isolinux/
    isolinux.cfg                  - конфигурационный файл
    isolinux.bin                  - загрузчик
    vmlinuz                        - ядро с поддержкой initrd
    initrd.gz                        - стартовая файловая система

Рассмотрим файл isolinux.cfg:

label linux
    kernel vmlinuz
    append initrd=initrd.gz

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

А что насчёт initrd и rootfs? Обе системы EXT2 размером в 4 MB являются сжатыми файлами. Ниже приведён скрипт для их создания:

BASE=/src/iso
SRC=$BASE/initrd
$DEST=$BASE/cdimage/isolinux/initrd
dd if=/dev/zero of=$DEST bs=1k count=4096
/sbin/losetup /dev/loop1 $DEST
mkfs -t ext2 -m 0 /dev/loop1
mount /dev/loop1 /mnt
cd $SRC
tar cf - . | (cd /mnt ; tar xf -)
umount /mnt
/sbin/losetup -d /dev/loop1
gzip -f $DEST

Для записи болванки следует показанное выше дерево каталогов в /src/iso/cdimage собрать в образ диска:

mkisofs -o /iso.img -b isolinux/isolinux.bin -c isolinux/boot.cat \
    -no-emul-boot -boot-load-size 4 -boot-info-table -l \
    -R -r /src/iso/cdimage

Файл boot.cat будет создан в результате выполнения этой команды. Опции -l, -R и -r нужны для расширения RockRidge (см. CD-Writing HowTo), которое позволяет использовать на CD-диске символические ссылки и имена со строчными и прописными буквами. Полученный файл следует записать на CD-диск с помощью cdrecord (оставим это в качестве домашнего задания :). А продвинутые пользователи могут протестить получившийся дистрибутив с помощью vmWare.

Основа для дальнейшего усовершенствования

Как же добавить особенную, необходимую только вам, функциональность к данному дистрибутиву? Как было упомянуто выше, каталог /usr является символической ссылкой на на каталог /usr на CD-диске. Используйте эту возможность!

Использование FrameBuffer

Приятно иметь графическую среду во время загрузки с CD. Для достижения максимальной совместимости следует активировать режим FrameBuffer для консоли и использовать X-сервер XF86_FBDev. Следует отметить, что FrameBuffer работает на видеокартах, которые имеют поддержку VESA 2.0, для более старых следует использовать простую консоль. Ниже приведены настройки ядра для активации FrameBuffer.

[*] VGA text console
[*] Video mode selection support
[*] Support for frame buffer devices (EXPERIMENTAL)
[*] VESA VGA graphics console
[*] Advanced low level driver options
    <*> 8 bpp packet pixels support
    <*> 16 bpp packet pixels support
    <*> 24 bpp packet pixels support
    <*> 32 bpp packet pixels support
    <*> VGA character/attributes support
[*] Select compiled-in fonts
    [*] VGA 8x8 font
    [*] VGA 8x16 font

Теперь следует указать правильный графический режим, который будет использоваться X-сервером. Для этого небходимо указать специфическую опцию для ядра. Таким образом, необходимо внести изменения в файл isolinux/isolinux.cfg:

label linux
    kernel vmlinux
    append initrd=initrd.gz vga=791


Загадочное число "791" обозначает графический режим 1024x768x16bit. Но такое жёсткое указание видеорежима не подойдет для всех случаев. Надо позволить пользователю выбирать требуемый графический режим. Перепишем
isolinux/isolinux.cfg:

timeout 30
prompt 1
display menu.txt
default 1

label 1
    kernel vmlinuz
    append initrd=initrd.gz

label 2
    kernel vmlinuz
    append initrd=initrd.gz vga=788

label 3
    kernel vmlinuz
    append initrd=initrd.gz vga=791


Файл menu.txt содержит следующее:

1) Text Mode
2) 800x600 x 16bit colour
3) 1024x768 x 16bit colour

Описано вроде всё. Теперь приступаем к созданию собственного дистрибутива...



 Design by Шишкин Алексей (Лёха)  ©2004-2008 by sources.ru