Создание 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

Ссылки

Личные инструменты