Linux Live CD - Основы
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
Описано вроде всё. Теперь приступаем к
созданию собственного дистрибутива...