Создание LiveCD на базе Gentoo
Материал из Belgorod Linux User Group - Белгород.
Содержание |
[править] Введение
Статья написана в рамках проекта "BLUG LiveCD" и описывает пошагово процесс создания собственного LiveCD. Обсуждение этого LiveCD на форуме:
http://belgorod.lug.ru/forum/index.php?topic=20.0
[править] Цель
Создать собственный LiveCD с минимальным необходимым набором ПО. Шустрого, оптимизированного под i686, но способного работать и на i486.
[править] Средства
Дистрибутив будем строить на базе Gentoo, т.к. он предоставляет очень гибкую систему заточки системы "под себя". Строиться LiveCD может на любой машине, желательно по мощнее :) У нас, к примеру, используется 8-процессорный Xeon с установленным Debian.
[править] Базовая система
Для начала мы должны создать базовую linux-систему, на которой будем строить свой LiveCD.
[править] stage 3
Все действия делаются от root-а (для сохранения прав).
sudo su -
Создаем директорию, где будет находится liveCD, в ней будет директория source, в которой будет храниться Linux и куда распакуем stage3 gentoo
mkdir -p /home/livecd/live-cd_minimal/source cd /home/livecd/live-cd_minimal/source tar -xjvf stage3-xxxxx.tar.bz2
[править] Заходим в новый Linux (work)
Для того чтобы работала система портов, нужны сами порты. Это может быть сетевой nfs путь или локальная директория, или их можно распаковать из тарбола, или выкачать по emerge --sync. В нашем примере это NFS директори. Затем надо Chroot-нуться в наш новый Линукс. Для всего этого мы будем использовать скрипт, который монтирует все что надо, и chroot-ится. При выходе - он все возвращает на место. Это скрипт под названием work:
#!/bin/bash
livecd_dir=`pwd`
function err_ex
{
echo $1
exit $2
}
echo -n "mount..."
mount -t proc proc $livecd_dir/source/proc || err_ex 1
mount -o bind /dev/ $livecd_dir/source/dev || err_ex 1
mount -o bind /sys $livecd_dir/source/sys || err_ex 1
mount 172.22.244.107:/usr/portage $livecd_dir/source/usr/portage || err_ex 2
cp /etc/resolv.conf $livecd_dir/source/etc/
echo ok
chroot `pwd`/source /bin/bash
echo -n "umount..."
umount $livecd_dir/source/usr/portage
umount $livecd_dir/source/proc
umount $livecd_dir/source/dev
umount $livecd_dir/source/sys
rm $livecd_dir/source/etc/resolv.conf
echo ok
С ним вход и выход в наш linux будет происходить быстро и безболезненно, выполнив просто
./work .... exit
[править] Оптимизация
Редактируем /etc/make.conf нужным нам образом, к примеру так:
# we want to work on x86
# >= i486 because glibc>2.4 & NPTL problem on i386
CHOST="i486-pc-linux-gnu"
# but tune to i686 ;)
CFLAGS="-O2 -mtune=i686 -pipe -fomit-frame-pointer -s"
CXXFLAGS="${CFLAGS}"
ACCEPT_KEYWORDS="~x86"
# system
USE="reiserfs usb nptl nptlonly unicode fbcon threads"
# wants
USE="$USE vim-syntax dhcp bash-completion samba curl "
# - minus
USE="$USE -ipv6 -acl -X -fortran -openmp -java -doc -berkdb -selinux -readline"
LINGUAS="ru"
FEATURES="-sandbox -unmerge-orphans"
# we have many CPUs ;)
MAKEOPTS="-j9"
[править] Пересборка
Пересобираем все что есть, под наши флаги:
emerge -e world
обновляем конфиги:
etc-update или dispatch-conf
[править] Доставляем все что нужно
Ставим по emerge все что нужно, на текущий момент наш /var/lib/portage/world выглядит так (что ставилось):
app-admin/ide-smart app-admin/sudo app-admin/testdisk app-arch/p7zip app-cdr/bin2iso app-cdr/cdrtools app-cdr/dvd+rw-tools app-dicts/aspell-ru app-dicts/ispell-ru app-editors/hexcurse app-editors/hexedit app-editors/vim app-i18n/enca app-misc/mc app-misc/screen app-portage/gentoolkit app-shells/zsh app-vim/pam-syntax app-vim/vim-spell-en app-vim/vim-spell-ru app-vim/vimcommander dev-lang/python media-fonts/terminus-font media-gfx/splash-themes-gentoo media-gfx/splash-themes-livecd media-gfx/splashutils net-analyzer/ettercap net-analyzer/iptraf net-analyzer/net-snmp net-analyzer/netcat net-analyzer/nmap net-analyzer/tcpdump net-analyzer/traceroute net-analyzer/xprobe net-dialup/minicom net-dialup/pppconfig net-dialup/pptpclient net-firewall/iptables net-fs/autofs net-fs/nfs-utils net-ftp/ftp net-ftp/lftp net-ftp/vsftpd net-mail/fetchmail net-misc/curl net-misc/dhcp net-misc/dhcpcd net-misc/netkit-talk net-misc/telnet-bsd net-misc/whois sys-apps/iproute2 sys-apps/memtest86 sys-apps/memtest86+ sys-apps/pciutils sys-apps/smartmontools sys-apps/xinetd sys-boot/grub sys-devel/gcc sys-fs/avfs sys-fs/dmraid sys-fs/fuse sys-fs/lvm2 sys-fs/ntfsprogs sys-fs/reiser4progs sys-fs/reiserfsprogs sys-fs/xfsprogs sys-libs/cracklib sys-libs/pam sys-process/atop sys-process/htop sys-process/lsof
[править] Локализация
Настраиваем конфиги, примерно как сказано тут: Локализация
[править] Настройка
[править] grub
в /boot/grub/menu.lst пишем:
default 0
timeout 10
title=Blug-LiveCD
root (cd)
kernel (cd)/boot/vmlinuz vga=791 \
root=/dev/ram0 init=/linuxrc \
looptype=squashfs loop=/livecd.squashfs udev nodevfs \
cdroot splash=silent,theme:newtheme
initrd (cd)/boot/initrd
можно еще дописать сюда memtest:
title=Memtest86
root (cd)
kernel (cd)/boot/memtest86/memtest.bin
title=Memtest86+
root (cd)
kernel (cd)/boot/memtest86plus/memtest.bin
[править] fstab
в /etc/fstab пишем:
/dev/loop0 / squashfs defaults 0 0 none /proc proc defaults 0 0 none /dev/shm tmpfs defaults 0 0
[править] Ядро
После сборки ядра, по умолчанию make install делает symlinc с vmlinuz на vmlinuz-2.6....., по этому если вы в заргузчике указываете ядро как vmlinuz, то следует удалить симлинку и скопировать файл физически, так как iso9660 не понимает симлинков, и ваше ядро не подхватится!
[править] initrd
Задача initrd - найти CDROM, смонтировать от туда наш образ (squashfs) в RAM, а потом передать управление уже init-у от туда. Для этой цели внутри initrd будет использоваться busybox.
[править] busybox
Копируем себе Busybox:
mkdir ./source/root/tmp/ cp ./busybox-1.10.1.tar.bz2 ./source/root/tmp/
переходим в LiveCD и собираем busybox:
./work cd /root/tmp tar -xjf ./busybox-1.10.1.tar.bz2 cd ./busybox-1.10.1 make defconfig cp .config .config.orig sed -e "s/# CONFIG_STATIC is not set/CONFIG_STATIC=y/gi" .config.orig > .config make
Все. BusyBox Собран. Выходим, забираем busybox себе:
exit mkdir ./initrdimage cp ./source/root/tmp/busybox-1.10.1/busybox ./initrdimage/ rm -fr ./source/root/tmp/
[править] структура initrd
Теперь нам нужно наполнение нашего initial ram disk-а. Это будет структура файловая и init-скрипты. Вот архив с готовой структурой. Ее можно создать вручную, мы взяли ее из Gentoo:
Изображение:Initrdimagesource.tar.gz
mkdir ./initrdimage/source tar -xzf initrdimagesource.tar.gz -C ./initrdimage/source
Можно отредактировать инит-скрипт по желанию
vim ./initrdimage/source/init
[править] mkinitrd
Далее нам все это надо завернуть в файл initrd. Это сжатый gzip-ом образ файловой системы. Скрипт, который это делает будет примерно такой (взято по образу и подобию из gentoo livecd-ng):
#!/bin/bash
pwd=`pwd`
# source with initrd structure & busybox executable here!
CD_INITRDIMAGE=$pwd/initrdimage
# here we make a initrd
CD_BUILDROOT=$pwd/initrd-root
CD_BUILDTEMP=${CD_BUILDROOT}/tmp/livecd
CD_BUILDCHROOT=${CD_BUILDROOT}/cdroot
if [ -d "$CD_BUILDROOT" ]; then
echo clearing...
rm -fr $CD_BUILDROOT/*
fi
mkdir -pv $CD_BUILDTEMP
mkdir -pv $CD_BUILDROOT
mkdir -pv $CD_BUILDCHROOT
initrd_create() {
echo creating
install -d ${CD_BUILDCHROOT}-initrd
dd if=/dev/zero of=${CD_BUILDROOT}/initrd bs=1k count=3000
mke2fs -F -q -N3000 ${CD_BUILDROOT}/initrd
mount -t ext2 -o loop ${CD_BUILDROOT}/initrd ${CD_BUILDCHROOT}-initrd
#makeinitrd
if [ ! -e ${CD_BUILDCHROOT}-initrd/bin ]
then
install -d ${CD_BUILDCHROOT}-initrd/{bin,etc,usr,proc,tmp}
ln -s bin ${CD_BUILDCHROOT}-initrd/sbin
ln -s ../bin ${CD_BUILDCHROOT}-initrd/usr/bin
ln -s ../bin ${CD_BUILDCHROOT}-initrd/usr/sbin
install -d ${CD_BUILDCHROOT}-initrd/keymaps
fi
# copy initrd structure
cp -R $CD_INITRDIMAGE/source/* ${CD_BUILDCHROOT}-initrd/
# copy busybox
cp -v $CD_INITRDIMAGE/busybox ${CD_BUILDCHROOT}-initrd/bin || die
# Generate busybox links. We really do not need all of them but its good to
# have a fall back in case we need them someday.
for i in '[' ash basename cat cut sed chroot clear cp dirname echo env false find \
grep gunzip gzip insmod ln ls loadkmap losetup lsmod mkdir mknod modprobe more mount mv \
pivot_root ps pwd rm rmdir rmmod sh sleep tar test touch true umount uname mdev \
xargs yes zcat chmod chown; do
rm -f ${CD_BUILDCHROOT}-initrd/bin/$i
ln ${CD_BUILDCHROOT}-initrd/bin/busybox ${CD_BUILDCHROOT}-initrd/bin/$i || die
done
install -d ${CD_BUILDCHROOT}-initrd/modules/storage
if [ "$LOOP_MODE" = "cloop" ]
then
cp ${CD_BUILDTEMP}/${CLOOP_DIR}/cloop_ucl.o ${CD_BUILDCHROOT}-initrd/modules/cloop.o || die "can't find ucl cloop module"
fi
local mymod
for i in $STORAGE_MODULES
do
mymod=`find ${CD_BUILDCHROOT}/lib/modules -name "${i}.o"`
if [ -z "${mymod}" ]
then
echo "Error: ${i}.o not found; skipping..."
continue
fi
cp $mymod ${CD_BUILDCHROOT}-initrd/modules/storage
done
#make initrd
umount ${CD_BUILDCHROOT}-initrd
gzip -f -9 ${CD_BUILDROOT}/initrd
}
initrd_create
echo initrd created!
cd $pwd
# copy result initrd to our live cd
cp -v ${CD_BUILDROOT}/initrd.gz ./source/boot/initrd
Все. Если все нормально - по выполнении этого скрипта в ./source/boot/ появится наш initrd
[править] Заворачиваем squashfs
На хост-машине (где все собираем ставим squashfs-tools):
apt-get install squashfs-tools
ВНИМАНИЕ!!!
Версия squashfs должна быть одинакова на машине, на которой будет проходить ее создание (на хост-машине), и в ядре самого LiveCD! Иначе она не сможет распаковаться!
Мы к примеру используем SquashFS 3.3. По этому
mksquashfs -version
должен показывать 3.3 и в ядре самого Линукса LiveCD:
File systems ---> Miscellaneous filesystems ---> <*> SquashFS 3.3 - Squashed file system support
Далее для создания iso-образа будем использовать приведенный ниже скрипт. Он скопирует все что нужно в диреторию target, подчистит ее немного и завернет наш LiveCD в squashfs. После чего создаст iso-образ. copy_to_target:
#!/bin/bash
pref=`pwd`
function err_ex
{
echo $1
exit $2
}
# check have all required soft
which which > /dev/null 2>&1 || err_ex "Can't find witch. Try install sys-apps/which." 4
which rsync > /dev/null 2>&1 || err_ex "Can't find rsync. Try install net-misc/rsync." 5
which mksquashfs > /dev/null 2>&1 || err_ex "Can't find mksquashfs. Try install sys-fs/squashfs-tools." 6
which mkisofs > /dev/null 2>&1 || err_ex "Can't find mkisofs. Try install app-cdr/cdrtools." 7
#find $pref/source/ -type f -xdev -name ".keep" -print -exec rm {} \;
echo -n "cleanup and prepare target..."
rm -rf $pref/target
mkdir $pref/target
cp -a $pref/source/boot $pref/target/
mkdir -p $pref/target/files/source
echo ok
echo -n "rsync copy source to target..."
rsync -a -q --delete --progress --exclude "var/tmp/*" --exclude "var/cache/*" --exclude "usr/portage" --exclude "etc/portage" --exclude "usr/share/doc" --exclude "usr/src" $pref/source/ $pref/target/files/source/
echo ok
echo "cleanup trash from target..."
cd $pref/target/files/source/
rm -rf var/tmp/*
rm -rf var/run/*
rm -rf var/lock/*
rm -rf var/cache/*
rm -rf var/db
rm -rf tmp/*
rm -f etc/mtab
rm -rf boot/
touch etc/mtab
rm -rf var/log
mkdir var/log
mkdir var/lib/dhcpc
rm -rf usr/portage
rm -rf etc/portage
rm -rf usr/share/doc
rm -rf usr/src/
rm root/.bash_history
echo "ok"
# ADDED DELETE !!!
if [ -d $pref/files_to_delete ]; then
for file_del in `ls $pref/files_to_delete/`
do
for i in `cat $pref/files_to_delete/$file_del`
do
rm -f $pref/target/files/source$i
done
done
fi
# END
cd $pref/target/files
time mksquashfs source/ $pref/target/livecd.squashfs
touch $pref/target/livecd
rm -rf $pref/target/files
cd $pref
mkisofs -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -iso-level 4 -hide-rr-moved -c boot.catalog -o $pref/livecd.iso $pref/target/
[править] Проверка
Для проверки будем использовать эмулятор. К примеру KVM (QEMU). Скрипт запуска виртуальной машины будет примерно следующим:
#!/bin/bash
cdir="/home/virtual/livecd"
par="-nographic"
kvm -cdrom /home/virtual/livecd/current.iso -boot d -m 512 \
-net nic,vlan=6,model=rtl8139,macaddr=52:54:05:07:15:77 -net tap,vlan=6 -vnc 192.168.0.1:7 \
-daemonize -pidfile $cdir/process.pid
Скрипт останова:
#!/bin/bash
cdir="/home/virtual/livecd"
ps ax | grep -v grep | grep `cat $cdir/process.pid` 2>&1 > /dev/null
if [ $? -eq 0 ]; then
echo "Killing"
kill -9 `cat $cdir/process.pid`
else
echo "this virtual mashine not running"
fi
Для подключения к виртуальной машине с клиентского PC, использовать vncviewer:
vncviewer 192.168.0.1:7
Если все ок - нарезаем болванку, и проверяем на настоящем PC.
cdrecord -sao -speed=24 dev=/dev/hdd current.iso

