АВТОР: Mike Hernandez
ПЕРЕВОД: Сергей Каминский
ДАТА: 2005-09-03
ЛИЦЕНЗИЯ: GNU Free Documentation License Version 1.2
КОНСПЕКТИВНО: Руководство для начинающих по созданию Live CD из LFS 6.0
АЛЬТЕРНАТИВНОЕ РАСПОЛОЖЕНИЕ: Более свежую версию этого совета вы можете найти на http://www.culmination.org/Mike/2.6-udev-nptl-bootcd.txt
ОПИСАНИЕ:
Этот совет детально описывает, как я сделал Live CD из собранной системы LFS 6.0. Читатель может следовать этому совету для создания своего собственного Live CD. Этот совет был адаптирован из "Простого" совета для работы с LFS 6.0. Это моя попытка сделать его как можно проще для тех, кто создает Live CD впервые.
ТРЕБОВАНИЯ:
1. Рабочая LFS система (и cdrtools, если вы хотите записывать cd)
2. LFS система, созданная для создаваемого Live CD (смотрите ниже)
3. CD Writer + Media
4. Syslinux (http://freshmeat.net/projects/syslinux/)
Перед началом, позвольте мне сделать небольшое вступление. Я назвал этот раздел: Что это и для чего
ЧТО ЭТО
Это совет по созданию простого Live CD. Для большей точности: После загрузки с CD пользователь попадает в приглашение linux.
Если вы собираете его из системы LFS (без компонентов BLFS), то CD будет полезен для восстановления поврежденной LFS системы.
Создание Live CD может быть интересным, а знание того, как это сделать, открывает двери к большим возможностям. Этот совет является хорошей отправной точкой для воплощения идеи о "полном спасательном CD".
ДЛЯ ЧЕГО
Как я сказал выше, это поможет вам сделать простой Live CD. Пользователь попадет в приглашение linux и ничего кроме этого, если вы сами не добавите функциональности.
Этот совет не описывает размещение на CD тонн программ, которые вы можете обнаружить на knoppix или официальном LFS загружаемых CD.
Этот совет не описывает создание программы установки для копирования содержимого CD на жесткий диск.
Так же вы не найдете здесь информацию о кросс-компилировании, поэтому если вы хотите, чтобы ваш CD загружался на архитектуре, полностью отличной от вашей, то вы должны иследовать этот вопрос самомтоятельно.
ПОЧЕМУ ОН ИМЕННО ТАКОЙ
Этот совет создан для помощи тем, кто создает Live CD впервые. Я пытался сделать его как можно проще, поэтому он не будет требовать для выполнения слишком глубокого понимания LFS (совет, на котором он основывается, назывался "Простой совет по созданию загрузочного CD"). Конечно, вам надо иметь некоторые знания, но знания эксперта не требуются. Создание установочного CD, или использование таких файловых систем, как squashfs, для начинающих может потребовать больше информации и попытка включения всего этого может сделать этот совет больше беспорядочным, чем полезным.
НАЧАЛО
Этот совет, как и совет на котором он основан, требует, чтобы у читателя были собраны две системы. Одна система - это ваша обычная рабочая система, которую вы будете использовать для записи CD после его подготовки. Вторая - это система, созданная специально для размещения ее на Live CD. Если вы хотите загружать CD только на машине, на которй его создали, то просто сделайте копию вашей LFS системы на другом разделе.
Вы можете удивиться, зачем вам нужны две системы для создания Live CD. Реально смысл очень простой. Если вы как я, то вы оптимизируете вашу LFS систему для вашего РС (или в моем случае лаптопа). У меня система на базе Pentium 4, поэтому все программы, поддерживающие оптимизацию, были собраны с:
CFLAGS='-march=pentium4'
И в чем проблема? Она в том, что я хочу, чтобы мой Live CD запускался везде, где поддерживается загрузка с CD! Программі в моей текущей системе не запустятся на машине, которая не pentium 4. Во время сборки я использую на много больше оптимизаций, но здесь я упоминаю архитектуру, поскольку это подводит к важной точке:
ЗНАЙТЕ ЗАРАНЕЕ, НА КАКОМ ОБОРУДОВАНИИ ВЫ ХОТИТЕ ЗАГРУЖАТЬ CD!
Перед началом вы должны решить, что должен делать ваш Live CD. Вы можете захотеть рассмотреть возможность оптимизировать все в вашей Live CD системе по объему или для особого типа машины или не оптимизировать вообще. Что лучше - решать вам.
Другой смысл наличия отдельной системы - это то, что при создании CD мы создаем некоторые директории и перемещаем в них очень важные файлы. В случае, если что-то пойдет не так, то наличие как минимум начальной рабочей системы (если нет резервной копии Live CD системы) может спасти ситуацию.
НАСТРОЙКА ОКРУЖЕНИЯ
Чтобы сделать работу проще, вы должны установить переменную LIVECD с указанием на точку монтирования системы, которую вы будете использовать для CD:
export LIVECD=/mnt/livecd
Вы так же можете захотеть установить переменную CDDEV:
export CDDEV=/dev/ваше-устройство+раздел
Установите ISODIR на точку, где вы захотите держать образ:
export ISODIR=/где/у_вас/есть/место
НАСТРОЙКА Live CD СИСТЕМЫ
Теперь, когда все окружение установлено, настало время сделать некоторые окончательные настройки для Live CD системы. Это включает сборку ядра так, как вы хотите, и, возможно, добавление некоторых программ на ваше усмотрение.
Если вы абсолютно уверены, что ядро для вашей CD системы будет работать в системе, которую вы размещаете на CD, и вам не надо устанавливать любые другие программы для вашего CD, то вы можете перейти к разделу "Действия вокруг содержимого".
Перед тем, как мы сможем настроить и установить новое ядро для Live CD, мы войдем в систему в chroot окружении:
1. Подмонтируем вашу Live CD систему:
mkdir -p $LIVECD
mount $CDDEV $LIVECD
2. Согласно директивам книги LFS-6.0, подмонтируем виртуальные файловые системы перед входом в chroot:
mount -t proc proc $LIVECD/proc
mount -t sysfs sysfs $LIVECD/sys
mount -f -t ramfs ramfs $LIVECD/dev
mount -f -t tmpfs tmpfs $LIVECD/dev/shm
mount -f -t devpts -o gid=4,mode=620 devpts $LIVECD/dev/pts
3. Выполняем chroot в Live CD систему при помощи команды, указанной в конце главы 6 (НЕ КОМАНДЫ CHROOT В НАЧАЛЕ!!!).
chroot $LIVECD /usr/bin/env -i \\
HOME=/root TERM=$TERM PS1='\\u:\\w\\$ ' \\
PATH=/bin:/usr/bin:/sbin:/usr/sbin \\
/bin/bash --login
4. Монтируем ramfs и заполняем /dev
mount -n -t ramfs none /dev
/sbin/udevstart
5. Создаем необходимые символические ссылки и директории, не созданные udev:
ln -s /proc/self/fd /dev/fd
ln -s /proc/self/fd/0 /dev/stdin
ln -s /proc/self/fd/1 /dev/stdout
ln -s /proc/self/fd/2 /dev/stderr
ln -s /proc/kcore /dev/core
mkdir /dev/pts
mkdir /dev/shm
6. Выполняем монтирование виртуальных файловых систем (ядра):
mount -t devpts -o gid=4,mode=620 none /dev/pts
mount -t tmpfs none /dev/shm
Теперь вы в chroot, поэтому вы можете настроить и собрать ядро для CD. Если вы абсолютно уверены, что ядро для вашей CD системы будет работать в системе, которую вы размещаете на CD, то вы можете пропустить эту часть и просто устанавливать необходимые программы.
Сборка ядра для вашего Live CD не является чем-то, что легко только для ветерана! Есть такие опции, которые должны быть встроенными, и такие, которые должны быть выполнены в виде модулей. Я подразумеваю, что если вы чувствуете, что готовы к созданию Live CD вне вашей системы, то вы знаете, что делаете. Я предлагаю не использовать модули, так как это может создать проблемы если вы хорошо не знаете всего, что обеспечивает работу при использовании модулей с ядром 2.6 и udev. Будьте осторожны! =)
После установки вашего ядра вы можете захотеть проверить его работоспособность. Как только вы все установите, вы должны покинуть chroot и выполнять все остальные команды из вашей рабочей системы как root.
ДЕЙСТВИЯ ВОКРУГ СОДЕРЖИМОГО
A.K.A. Перемещение /dev /etc /home /root /tmp /var в /fake/needwrite
Когда я следовал "Простому" совету, я пришел к этому месту и воскликнул: Что такое /fake/needwrite? (реально это было больше похоже на "что черт возьми такое /fake/needwrite stuff?") Здесь находится ответ для тех из вас, кто сказал то же самое:
Директория /fake/needwrite используется для содержания файлов, которые должны быть записываемыми во время запуска Live CD. Обычно эти файлы не могут оставаться на CD-ROM, а поэтому они перемещаются в место, из которого они будут скопированы в электронный диск во время процесса загрузки CD. Нахождение файлов в электронном диске позволяет нам их изменять. Так же мы можем создавать файлы в директориях, расположеных в электронном диске, например в /tmp или /home.
Сначала мы должны создать директорию и точку монтирования для электронного диска:
* ЗАМЕЧАНИЕ: Если ваша CD система не подмонтирована, то выполните сейчас:
* mount $CDDEV $LIVECD
* благодарю Bernard за указание на это
mkdir -p $LIVECD/fake/{needwrite,ramdisk}
Теперь мы можем переместить сюда директории, для которых хотим сохранить доступ на запись:
cd $LIVECD/
mv dev/ etc/ home/ root/ tmp/ var/ fake/needwrite/
Теперь мы должны создать символические ссылки.
cd $LIVECD/
ln -s fake/needwrite/dev dev
ln -s fake/needwrite/var var
ln -s fake/needwrite/tmp tmp
ln -s fake/needwrite/root root
ln -s fake/needwrite/home home
ln -s fake/needwrite/etc etc
В этом месте выполните ls -l. Вывод должен быть таким:
dev -> fake/needwrite/dev
etc -> fake/needwrite/etc
home -> fake/needwrite/home
root -> fake/needwrite/root
tmp -> fake/needwrite/tmp
var -> fake/needwrite/var
СОЗДАНИЕ ПРОЦЕССА ЗАГРУЗКИ CD ПО НАШИМ ТРЕБОВАНИЯМ
Ok, у нас есть директории /etc /dev /var /tmp /root /home, слинкованные в директорию /fake/needwrite, которая установлена только для чтения (так как она на CD). Для возможности регистрации (и для запуска сервисов, требующих доступ на запись в /dev /var /tmp /root /home или /etc) мы должны вызвать скрипт из нашей директории /etc/rc.d/init.d/, который монтирует электронный диск на /fake/needwrite с доступом на запись.
Следующий скрипт создает два электронных диска, один временный, а другой будет домашней директорией с правами записи. Он копирует файлы с CD во временный электронный диск, а затем из него в окончательный электронный диск.
Оригинальный совет использовал один электронный диск, но это привело меня к большим проблемам. Во-первых, initrd, который загружается во время запуска, использует первый электронный диск (/dev/ram0). Следовательно, попытка примонтировать /dev/ram0 в другое место приведет к ошибке "устройство уже примонтировано". Во-вторых, отмонтирование электронного диска приводит к потере всех файлов. Оригинальный совет отмонтировал электронный диск и перемонтировал его, выполняя файлы, все еще находящиеся там. Что не работало у меня, вот почему я сделал так, что /dev/ram{0,1,2} есть всегда и рекомендую, чтобы вы делали так же. Если они отсутствуют, вы должны проверить установки вашего udev. Вы можете попробовать использовать mknod для создания этих фалов, но с этого момента я скажу, что если у вас нет устройств /dev/ram, то вы должны провести некоторые собственные исследования для поиска причин.
* Bernard для выполнения этого предложил цикл for, который вы можете попробовать:
* for i in 0 1 2 3 4 5 6 7; do
* mknod $LIVECD/dev/ram$i b 1 $i;
* done
Скопируйте и вставьте следующий скрипт и исправьте его для ваших потребностей, если необходимо:
cat > $LIVECD/etc/rc.d/init.d/create_ramdisk << "EOF"
#!/bin/sh
# УСТАНОВКА НЕКОТОРЫХ ПЕРЕМЕННЫХ ДЛЯ УСТРОЙСТВ И ДИРЕКТОРИЙ
dev_ram=/dev/ram1
dev_ram2=/dev/ram2
dir_ramdisk=/fake/ramdisk
dir_needwrite=/fake/needwrite
# УКАЗАНИЕ ФАЙЛА ФУНКЦИЙ
source /etc/rc.d/init.d/functions
case "$1" in
start)
# СОЗДАНИЕ ЭЛЕКТРОННОГО ДИСКА
echo "Creating ext2fs on $dev_ram..."
/sbin/mke2fs -m 0 -i 1024 -q $dev_ram > /dev/null 2>&1
evaluate_retval
sleep 1
# МОНТИРОВАНИЕ ЭЛЕКТРОННОГО ДИСКА
echo "Mounting ramdisk on $dir_ramdisk..."
mount -n $dev_ram $dir_ramdisk -t ext2
evaluate_retval
sleep 1
# КОПИРОВАНИЕ ФАЙЛОВ В ЭЛЕКТРОННЫЙ ДИСК
echo "Copying files to ramdisk..."
cp -a $dir_needwrite/* $dir_ramdisk > /dev/null 2>&1
evaluate_retval
sleep 1
# СОЗДАНИЕ ВТОРОГО ЭЛЕКТРОННОГО ДИСКА
echo "Creating second ramdisk"
/sbin/mke2fs -m 0 -i 1024 -q $dev_ram2 > /dev/null 2>&1
evaluate_retval
sleep 1
# МОНТИРОВАНИЕ ВТОРОГО ЭЛЕКТРОННОГО ДИСКА
echo "Mounting second ram disk"
mount -n $dev_ram2 $dir_needwrite -t ext2
evaluate_retval
sleep 1
# КОПИРОВАНИЕ ФАЙЛОВ ВО ВТОРОЙ ЭЛЕКТРОННЫЙ ДИСК
echo "Copying files to the second ram disk"
cp -a $dir_ramdisk/* $dir_needwrite
evaluate_retval
sleep 1
# ОТМОНТИРОВАНИЕ ПЕРВОГО ЭЛЕКТРОННОГО ДИСКА
echo "Unmounting and clearing first ram disk"
umount -n $dir_ramdisk > /dev/null 2>&1
blockdev --flushbufs /dev/ram1
evaluate_retval
sleep 1
;;
*)
echo "Usage: $0 {start}"
exit 1
;;
esac
EOF
Сделаем скрипт исполняемым при помощи следующей команды:
chmod 0755 $LIVECD/etc/rc.d/init.d/create_ramdisk
Gabe Munoz указал, что эта символическая ссылка может быть S11 там, где она используется как S00. Конечно, вы можете свободно выбирать номер ссылки (это ведь LFS !). Просто убедитесь, что вы не запускаете другие скрипты, которые попытаются записать в одну из директорий, которые требуют права записи перед перезаписью файлов.
cd $LIVECD/etc/rc.d/rcsysinit.d
ln -s ../init.d/create_ramdisk S00create_ramdisk
Затем мы должны установить загрузчик, isolinux. Он доступен в пакете syslinux. Вы можете найти syslinux на freshmeat:
http://freshmeat.net/projects/syslinux/
Указания ниже подразумевают, что тарбол syslinux-2.11.tar.bz2 уже размещен в $LIVECD/usr/src. (используйте текущую версию, 2.11 может быть уже устаревшей).
cd $LIVECD/usr/src
tar xzf syslinux-2.11.tar.gz
mkdir $LIVECD/isolinux
cp syslinux-2.11/isolinux.bin $LIVECD/isolinux
mv $LIVECD/boot/* $LIVECD/isolinux
cd $LIVECD/
rmdir boot
ln -s isolinux boot
Для загрузчика нужен файл конфигурации. Команда cat ниже создает этот файл.
* Замечание: Будьте осторожны с именем вашего ядра!
* Просмотрите http://syslinux.zytor.com/errors.php
* Используйте простые и понятные имена.
cat > $LIVECD/isolinux/isolinux.cfg << "EOF"
default livecd
label livecd
kernel lfskernel
append initrd=initrd.gz root=/dev/ram0 init=/linuxrc ramdisk_size=16384
EOF
На этом этапе можно изменить /etc/fstab Live CD системы. Удалите все, что вам не нужно (т.е. все строчки /dev/hd*). Вам нужны только proc и devpts.
vi $LIVECD/etc/fstab
Не беспокойтесь о монтировании корневой файловой системы "/". Она будет монтироваться скриптом linuxrc из начального электронного диска.
Вам может пригодится удаление следующих ссылок:
rm $LIVECD/etc/rc.d/rc3.d/S20network
rm $LIVECD/etc/rc.d/rc0.d/K80network
rm $LIVECD/etc/rc.d/rc6.d/K80network
rm $LIVECD/etc/rc.d/rcsysinit.d/S40mountfs
rm $LIVECD/etc/rc.d/rcsysinit.d/S30checkfs
Ok! Так далеко и все хорошо и правильно?! Для обеспечения работы процессов загрузки мы создадим начальный электронный диск. Больше информации о начальном электронном диске (для краткости initrd) может быть найдено в документации вашего ядра.
Инструкции ниже создают initrd:
dd if=/dev/zero of=$LIVECD/boot/initrd bs=1024 count=6144
mke2fs -m 0 -i 1024 -F $LIVECD/boot/initrd
mount -o loop $LIVECD/boot/initrd $LIVECD/mnt
cd $LIVECD/mnt
mkdir bin sbin lib dev proc mnt sys etc
cp -a $LIVECD/bin/{bash,mount,grep,umount,echo,ln,mkdir} bin/
cp -a $LIVECD/sbin/udev* sbin/
cp -a $(find $LIVECD -name "test" -type f) bin/
cp -a $(find $LIVECD -name "chroot" -type f) bin/
cp -a $(find $LIVECD -name "pivot_root" -type f) bin/
cp -H $LIVECD/lib/{libncurses.so.5,libdl.so.2,libc.so.6,ld-linux.so.2} lib/
cp -H $LIVECD/lib/{libreadline.so.5.0,libhistory.so.5.0} lib/
cp -a $LIVECD/dev/{console,null,ram{0,1,2}} dev/
cp -a $LIVECD/etc/{udev,dev.d,hotplug.d} etc/
ln -s bash bin/sh
ln -s test bin/[
Первая программа, выполняемая ядром, это /linuxrc. Так как она отсутствует, создадим ее. Наш скрипт найдет CD в правильном CD-ROM накопителе, а затем подмонтирует его в качестве корневой файловой системы / и запустит /sbin/init 3.
Скопируйте и вставьте следующий скрипт и исправьте его для ваших потребностей, если необходимо:
cat > $LIVECD/mnt/linuxrc << "EOF"
#!/bin/sh
# ID это файл в корне заргужаемого LFS CD, используемый для определения CD.
ID="livecd"
TMP_MOUNT="/mnt"
PATH="/bin:/sbin:/usr/bin:/usr/sbin"
CHECK_TYPE="try_mount"
# МОНТИРУЕМ ФАЙЛОВЫЕ СИСТЕМЫ ЯДРА
# Создаем директорию proc, если ее нет
if [ ! -d "/proc/" ]; then
mkdir /proc
fi
# Монтируем файловую систему proc
mount -n proc /proc -t proc
# Если sysfs перечислена в /proc как правильная файловая система,
# то монтируем ее (если это не так, то udev не будет работать и
# у вас не будет необходимых устройств)
if grep -q '[[:space:]]sysfs' /proc/filesystems; then
if [ ! -d /sys/block ]; then
mount -n sysfs /sys -t sysfs
fi
fi
# Создадим некоторые вещи, которые sysfs не создает и не экспортирует для нас.
# Добавляйте устройства в этот список свободно.
make_extra_nodes() {
ln -s /proc/self/fd /dev/fd
ln -s /proc/self/fd/0 /dev/stdin
ln -s /proc/self/fd/1 /dev/stdout
ln -s /proc/self/fd/2 /dev/stderr
ln -s /proc/kcore /dev/core
mkdir /dev/pts
mkdir /dev/shm
}
if [ ! -x /sbin/hotplug ]; then
echo /sbin/udev > /proc/sys/kernel/hotplug
fi
# Монтируем временную файловую систему через /dev, так что
# любые устройства, созданные или удаленные во время этой загрузки,
# не влияют на дальнейший процесс.
# Мы не записываем в mtab поскольку не хотим, чтобы
# /dev был недоступен (например при `umount -a').
mount -n ramfs /dev -t ramfs
/sbin/udevstart
make_extra_nodes
# Определение Live CD является достаточно комплексным,
# но очень логичным процессом
# Ищем устройство cdrom и добавляем его в CDROM_LIST
CDROM_LIST=""
# Ищем в дереве proc устройства ide cdrom.
# Они использованы в качестве раздела в devfs, но это было
# отредактировано для udev. Возможно, мы реально не должны
# больше использовать /proc, а вместо этого использовать sysfs...
# Возможно в будущем
# Проверяем ide каналы.
for ide_channel in /proc/ide/ide[0-9]
do
# Если ide каналы не обнаружены, то пропускаем
if [ ! -d "$ide_channel" ]; then
break
fi
# Проверяем каждое устройство ide на наличие cd-rom накопителя
for ide_device in hda hdb hdc hdd hde hdf hdg hdh hdi hdj hdk hdl hdm hdn
do
device_media_file="$ide_channel/$ide_device/media"
if [ -e "$device_media_file" ]; then
grep -i "cdrom" $device_media_file > /dev/null 2>&1
if [ $? -eq 0 ]; then
CDROM_LIST="$CDROM_LIST /dev/$ide_device"
fi
fi
done
done
# Проверяем scsi cd-rom
for scsi_cdrom in /dev/scd[0-99]
do
if [ -e "$scsi_cdrom" ]; then
CDROM_LIST="$CDROM_LIST $scsi_cdrom"
fi
done
# Теперь пытаемся найти загрузочный LFS CD (мы используем ID для идентификации)
LFS_CDROM_DEVICE=""
for cdrom_device in $CDROM_LIST
do
if [ "$CHECK_TYPE" = "try_mount" ]; then
mount -n -t iso9660 ${cdrom_device} $TMP_MOUNT # > /dev/null 2>&1
media_found=$?
fi
if [ $media_found -eq 0 ]; then
echo -n "media found"
if [ "$CHECK_TYPE" = "try_mount" ]; then
[ -e "$TMP_MOUNT/$ID" ]
media_lfs=$?
fi
if [ "$CHECK_TYPE" = "try_mount" ]; then
umount -n $cdrom_device > /dev/null 2>&1
fi
if [ $media_lfs -eq 0 ]; then
echo ", LFS boot CD found. Ready!"
LFS_CDROM_DEVICE="$cdrom_device"
break;
else
echo ", not LFS boot CD."
fi
else
echo "no media "
fi
done