2010
Установка Gentoo GNU/Linux без компиляции
Введение
Существует целый арсенал устройств, на которых сборка «Gentoo GNU/Linux» либо невозможна, либо затруднительна из-за недостатка аппаратных ресурсов, либо попросту бессмысленна. Это может быть VPS, нетбук или старый компьютер. А может быть и пул однотипных серверов с одинаковой архитектурой и одинаковым программным обеспечением. В любом из этих случаев предпочтительна сборка системы на другом, достаточно мощном, компьютере, выступающем в роли репозитория бинарных пакетов.
На таком компьютере должен стоять любой дистрибутив на базе «GNU/Linux», той же архитектуры, что требуется конечному устройству, или виртуальная машина с необходимой архитектурой.
Я не буду рассказывать о кросс-компиляции для архитектуры, отличной от той, которая используется на компьютере. Это немного другая тема.
Дополнительно на этом компьютере потребуется настроенный http-сервер для возможности загрузки бинарных пакетов конечному устройству по сети. Можно любым другим способом монтировать репозиторий с бинарными пакетами в файловую систему на конечном устройстве или просто перенести на любом носителе все бинарные пакеты на конечное устройство, что немного неудобно в плане дальнейшего обновления.
Дополнительным преимуществом установки «Gentoo GNU/Linux» на конечное устройство из бинарных, предварительно собранных, пакетов является избавление от «мусора», который необходим только для сборки из исходных текстов, но не требуется для работы. Так же есть возможность освободить дополнительное место в системе, избавившись от исходных текстов ядра и дерева «Portage», занимающих вместе чуть больше одного гигабайта.
Итак, на выходе мы имеем всю быстроту работы и гибкость «Gentoo GNU/Linux» с возможностью не собирать пакеты на конечном устройстве, а устанавливать предварительно собранные на более мощном компьютере.
Для работы потребуются права суперпользователя.
Я расскажу как все это сделать на примере сборки «Gentoo GNU/Linux» для тестовой виртуальной машины, работающей на очень слабом, по современным меркам, ноутбуке с использованием небольшого сервера под управлением «Gentoo GNU/Linux», на котором и будет происходить весь процесс сборки необходимых бинарных пакетов.
Подготовка chroot-окружения
Для начала, нужно определиться с местом, где будет находиться наша система для сборки. Я для себя решил, что в «/srv/cfarm» ей самое место. Итак, создаем каталог «/srv/cfarm/test» и заходим в него.
# mkdir -p /srv/cfarm/test
# cd /srv/cfarm/test
Скачиваем «Stage3» с любого зеркала «Gentoo GNU/Linux» под свою архитектуру и распаковываем. В моем случае это будет i686-архитектура. Скачивать будем из «current-stage3», так как релиз совсем устарел. Для этого достаточно зайти на любое удобное зеркало «Gentoo GNU/Linux» в директорию «/releases/x86/current-stage3» и скачать последний снимок.
# wget http://distfiles.gentoo.org/releases/x86/autobuilds/current-stage3-i686/stage3-i686-hardened-hardened-hardened-hardened-hardened-20171212T011501ZT011501ZT011501ZT011501Z.tar.bz2
# tar -xjvpf ./stage3-i686-hardened-hardened-hardened-hardened-hardened-20171212T011501ZT011501ZT011501ZT011501Z.tar.bz2
Если распаковка прошла успешно, то можно удалить файл «Stage3» и содержимое «/srv/cfarm/test/dev».
# rm -f ./stage3-i686-hardened-hardened-hardened-hardened-hardened-20171212T011501ZT011501ZT011501ZT011501Z.tar.bz2
# rm -rf /srv/cfarm/test/dev/*
Нужно определится, где будет храниться дерево «Portage». Если компьютер, на котором будет выполняться сборка, работает под управление «Gentoo GNU/Linux», то все просто - вероятно дерево «Portage» уже находиться в «/usr/portage» или в другом месте, определенном переменной «PORTDIR» в файле «/etc/make.conf». Иначе, нужно будет скачать последний снимок дерева «Portage» и распаковать в отдельное место, например в «/srv/cfarm/portage». Так удобно поступить, если планируется создавать несколько chroot-окружений под различные конечные устройства. Дерево «Portage» будет для всех одно.
# wget http://de-mirror.org/distro/gentoo/releases/snapshots/current/portage-latest.tar.bz2
# tar -xjvpf portage-latest.tar.bz2 -C /srv/cfarm
# rm -f portage-latest.tar.bz2
Так же имеет смысл вынести из chroot-окружения загруженные архивы файлов исходных текстов в отдельную директорию, например «/srv/cfarm/distfiles». Таким образом можно использовать их в различных chroot-окружениях, не загружая каждый раз заново.
# mkdir -p /srv/cfarm/distfiles
Позаботимся заранее о будущих получаемых бинарных пакетах. Их тоже лучше вынести отдельно, чтобы дать возможность http-серверу увидеть их все в одном месте. Бинарные пакеты будем складывать в «/srv/cfarm/binhost».
# mkdir -p /srv/cfarm/binhost
Подготовим будущее chroot-окружение.
Скопируем файл «resolv.conf» из основной системы.
# cp -f /etc/resolv.conf ./etc/resolv.conf
Нужно задать временную зону, скопировав необходимый файл зоны в «/etc/localtime». В моем случае временная зона будет «Europe/Moscow».
# cp -f ./usr/share/zoneinfo/Europe/Moscow ./etc/localtime
Редактируем файл «/etc/make.conf».
# nano ./etc/make.conf
У меня получился следующий файл «/etc/make.conf».
make.confCHOST="i686-pc-linux-gnu"
CFLAGS="-O2 -march=i686 -pipe -fomit-frame-pointer"
LDFLAGS="-Wl,-O1 -Wl,--sort-common -Wl,--hash-style=gnu -Wl,--as-needed"
ACCEPT_KEYWORDS="~x86"
ACCEPT_LICENSE="PUEL"
PORTAGE_NICENESS="5"
MAKEOPTS="-j3"
PORTAGE_IONICE_COMMAND="ionice -c 3 -p \${PID}"
FEATURES="buildpkg ccache userpriv usersandbox usersync"
EMERGE_DEFAULT_OPTS="--alphabetical --verbose --nospinner --with-bdeps=y --keep-going"
INSTALL_MASK="/usr/share/gtk-doc"
PORTAGE_BINPKG_TAR_OPTS="-X /etc/portage/package.exclude"
PORTDIR="/var/portage/portage"
PKGDIR="/var/portage/packages"
DISTDIR="/var/portage/distfiles"
GENTOO_MIRRORS="http://de-mirror.org/distro/gentoo/
ftp://mirror.yandex.ru/gentoo-distfiles/"
COLLISION_IGNORE="/usr/share/man/man1/maildirmake.1.bz2
/usr/share/man/man8/deliverquota.8.bz2
/usr/bin/maildirmake"
CCACHE_SIZE="1G"
CCACHE_DIR="/var/cache/ccache"
LINGUAS="ru"
LANGUAGE="ru"
VIDEO_CARDS="none"
LD_AS_NEEDED="1"
I_KNOW_WHAT_I_AM_DOING="yes"
USE="bash-completion bzip2
gd
charconv
network-cron
urandom
sse2
threads
vchroot vhosts
-berkdb
-fortran
-gdbm -gpm
-ipv6
-python
-tcpd
-sqlite"
Я сразу же изменил директории хранения дерева «Portage», архивов исходных кодов и место для хранения бинарных пакетов из «/usr/portage» в «/var/portage». Это видно по переменным «PORTDIR», «PKGDIR» и «DISTDIR». Поэтому надо создать соответствующие директории.
# mkdir -p ./var/portage/{portage,distfiles,packages}
Следует обратить внимание на переменную «ACCEPT_KEYWORDS». Не всем подойдет «сидеть под тильдой», то есть использовать тестовые версии пакетов. Мне это подходит, так как большинство ключевых пакетов на серверах необходимо держать всегда свежими.
Так же нужно посмотреть на переменную «CFLAGS» и заменить значение в опции «-march=…» на тип вашего процессора на конечном устройстве. Подробнее о настройках переменных «CHOST» и «CFLAGS» под различные типы процессоров можно посмотреть по ссылке «http://en.gentoo-wiki.com/wiki/Safe_Cflags».
Переменная «LDFLAGS» отвечает за опции линковки.
Переменная «FEATURES» должна содержать опцию «buildpkg», чтобы после установки приложений в chroot-окружении в директории «/var/portage/packages» создавались бинарные пакеты.
Переменная «PORTAGE_BINPKG_TAR_OPTS» указывает опции упаковки бинарных пакетов. А в файле «/etc/portage/package.exclude» будут храниться маски исключений при упаковке. Создадим этот файл.
# mkdir ./etc/portage
# nano ./etc/portage/package.exclude
package.exclude*/LICENSE*
*/README*
*.a
*.la
*.prl
*/.keep*
*/cmake*
*.cmake
*/examples*
*/etc/xinetd.d*
*/include*
*/mkspecs*
*/usr/bin/*-config
*/usr/bin/*-config-2
*/usr/lib/cmake*
*/usr/lib/pkgconfig*
*/usr/share/aclocal*
*/usr/share/apps/cmake*
*/usr/share/common-lisp*
*/usr/share/doc/*/html*
*/usr/share/getopt*
*/usr/share/gtk-doc*
*/usr/share/locale/a*
*/usr/share/locale/b*
*/usr/share/locale/c*
*/usr/share/locale/d*
*/usr/share/locale/e*
*/usr/share/locale/f*
*/usr/share/locale/g*
*/usr/share/locale/h*
*/usr/share/locale/i*
*/usr/share/locale/j*
*/usr/share/locale/k*
*/usr/share/locale/l*
*/usr/share/locale/m*
*/usr/share/locale/n*
*/usr/share/locale/o*
*/usr/share/locale/p*
*/usr/share/locale/ro*
*/usr/share/locale/rs*
*/usr/share/locale/rw*
*/usr/share/locale/s*
*/usr/share/locale/t*
*/usr/share/locale/u*
*/usr/share/locale/v*
*/usr/share/locale/w*
*/usr/share/locale/x*
*/usr/share/locale/y*
*/usr/share/locale/z*
*/usr/share/locale/l10n/a*
*/usr/share/locale/l10n/b*
*/usr/share/locale/l10n/c*
*/usr/share/locale/l10n/d*
*/usr/share/locale/l10n/e*
*/usr/share/locale/l10n/f*
*/usr/share/locale/l10n/g*
*/usr/share/locale/l10n/h*
*/usr/share/locale/l10n/i*
*/usr/share/locale/l10n/j*
*/usr/share/locale/l10n/k*
*/usr/share/locale/l10n/l*
*/usr/share/locale/l10n/m*
*/usr/share/locale/l10n/n*
*/usr/share/locale/l10n/o*
*/usr/share/locale/l10n/p*
*/usr/share/locale/l10n/q*
*/usr/share/locale/l10n/ro*
*/usr/share/locale/l10n/rs*
*/usr/share/locale/l10n/rw*
*/usr/share/locale/l10n/s*
*/usr/share/locale/l10n/t*
*/usr/share/locale/l10n/u*
*/usr/share/locale/l10n/v*
*/usr/share/locale/l10n/w*
*/usr/share/locale/l10n/x*
*/usr/share/locale/l10n/y*
*/usr/share/locale/l10n/z*
*/usr/share/man/a*
*/usr/share/man/b*
*/usr/share/man/c*
*/usr/share/man/d*
*/usr/share/man/e*
*/usr/share/man/f*
*/usr/share/man/g*
*/usr/share/man/h*
*/usr/share/man/i*
*/usr/share/man/j*
*/usr/share/man/k*
*/usr/share/man/lt*
*/usr/share/man/n*
*/usr/share/man/p*
*/usr/share/man/ro*
*/usr/share/man/rw*
*/usr/share/man/s*
*/usr/share/man/t*
*/usr/share/man/u*
*/usr/share/man/v*
*/usr/share/man/w*
*/usr/share/man/x*
*/usr/share/man/y*
*/usr/share/man/z*
*/usr/share/pkgconfig*
*/usr/share/rfc*
*/usr/share/sgml*
*/usr/share/sounds*
*/usr/share/templates*
*/usr/share/wallpapers*
Подробнее о настройке файла «/etc/make.conf» можно почитать в настольной книге «Gentoo GNU/Linux» по адресу «http://www.gentoo.org/doc/ru/handbook».
Работа в chroot-окружении
Все готово для перехода в chroot-окружение. Для этого я использую небольшой скрипт «cfarm-chroot.sh», который монтирует все необходимое, а при выходе из chroot-окружения - отмонтирует.
cfarm-chroot.sh#!/bin/bash
CFARM="/srv/cfarm"
PORTAGE="/srv/cfarm/portage"
DISTFILES="${CFARM}/distfiles"
BINHOST="${CFARM}/binhost"
PROFILE="${CFARM}/$1"
if [ ! -d "${PROFILE}" ]; then
echo "Directory ${PROFILE} not found"
exit 1
fi
if [ ! -d "${BINHOST}/$1" ]; then
mkdir -p "${BINHOST}/$1"
fi
if [ ! $(mount -l -t proc|cut -d ' ' -f3|grep ${PROFILE}/proc) ]; then
mount -t proc none ${PROFILE}/proc
mount -o bind /dev ${PROFILE}/dev
mount -o bind /dev/pts ${PROFILE}/dev/pts
mount -o bind ${PORTAGE} ${PROFILE}/var/portage/portage
mount -o bind ${BINHOST}/$1 ${PROFILE}/var/portage/packages
mount -o bind ${DISTFILES} ${PROFILE}/var/portage/distfiles
fi
COUNT=0
[ -f "/tmp/.cfarm-$1" ] && COUNT=$(cat "/tmp/.cfarm-$1")
(( COUNT++ ))
echo "${COUNT}" >"/tmp/.cfarm-$1"
chroot ${PROFILE} /bin/bash
COUNT=$(cat "/tmp/.cfarm-$1")
(( COUNT-- ))
echo "${COUNT}" >"/tmp/.cfarm-$1"
if [ "$(cat "/tmp/.cfarm-$1")" -le 0 ]; then
rm -f "/tmp/.cfarm-$1"
echo "Umount chroot ${PROFILE}..."
umount ${PROFILE}/var/portage/distfiles
umount ${PROFILE}/var/portage/packages
umount ${PROFILE}/var/portage/portage
umount ${PROFILE}/proc
umount ${PROFILE}/dev/pts
umount ${PROFILE}/dev
fi
Скопируйте содержимое скрипта в файл «/srv/cfarm/cfarm-chroot.sh», измените значения переменных «CFARM» и «PORTAGE» в начале скрипта на те, которые вам удобны и выполните следующее.
# chmod 755 /srv/cfarm/cfarm-chroot.sh
Чтобы как-то выделить chroot-окружение от других консолей, подправим файл «/srv/cfarm/test/etc/profile».
# echo 'PS1="(chrt test) $PS1"' >>/srv/cfarm/test/etc/profile
Далее все действия будем выполнять в созданном chroot-окружении. Для перехода в него выполните только что созданный скрипт, а в качестве параметра передайте ему имя директории внутри «/srv/cfarm».
# /srv/cfarm/cfarm-chroot.sh test
# env-update && source /etc/profile
Необходимо сразу же обновить дерево «Portage».
# emerge --sync
Теперь, как сказано в документации, нужно определиться с профилем системы. Смотрим список доступных профилей.
# eselect profile list
В моем случае подходит профиль «default/linux/x86/10.0»
Я не хочу делить профиль на «desktop» или «server», поэтому выполняю следующее.
# eselect profile set default/linux/x86/10.0
Так же нужно изменить файл «/etc/locale.gen», содержащий список необходимых локалей.
# nano /etc/locale.gen
У меня он выглядит следующим образом.
locale.genen_US.UTF-8 UTF-8
ru_RU.UTF-8 UTF-8
ru_RU.KOI8-R KOI8-R
ru_RU.CP1251 CP1251
ru_RU.IBM866 IBM866
Для ускорения компиляции установим пакет «dev-util/ccache».
# emerge ccache
Чтобы видеть статистику работы «ccache», выполним следующее.
# echo 'CCACHE_DIR="/var/cache/ccache"' >/etc/env.d/99ccache
# env-update && source /etc/profile
# ccache -s
Подготовим chroot-окружение для обновления «system». Посмотрим, что же хочет установиться и поправим USE-флаги в файле «/etc/make.conf».
# emerge system -ep
На момент написания еще не все работало с «python-3», поэтому два пакета «dev-lang/python» в системе мне не нужно.
# echo '>=dev-lang/python-3' >/etc/portage/package.mask
Позже, когда все используемые программы перейдут на использование «python-3», можно будет удалить строчку «>=dev-lang/python-3» из «/etc/portage/package.mask».
Все устраивает, за исключением USE-флагов пакета «sys-apps/util-linux». Но не будем изменять флаги в файле «/etc/make.conf», так как USE-флаги, которые не устраивают, будут влиять только на сборку этого конкретного пакета. Поэтому информацию о нем поместим в файл «/etc/portage/package.use».
# echo 'sys-apps/util-linux -crypt -perl' >>/etc/portage/package.use
Определить, куда удобнее прописать USE-флаг, в «/etc/make.conf» или «/etc/portage/package.use», можно только используя «Gentoo GNU/Linux» на протяжении некоторого времени. Однозначного ответа никто не даст.
Создание бинарных пакетов
Почти все готово для первой сборки «system». Осталось решить вопрос с бинарными пакетами. Ранее созданный файл «/etc/portage/package.exclude» уберет достаточно много «мусора» из бинарных пакетов, но этого недостаточно. Все равно будет создано большое количество пакетов c «лишними» файлами, которые позже попадут на конечное устройство. Необходим метод борьбы с этим явлением.
Первоначальная идея была использовать файл «/etc/portage/profile/package.provided» для исключения пакетов, необходимых только для сборки. Но ведение этого файла отнимает много времени и, в конечном итоге, не дает желаемого результата. Так же была идея грамотно настраивать переменную «RDEPEND» в файлах «.ebuild» дерева «Portage» и помещать их в локальный оверлей. Идея была так же отвергнута из за большой трудоемкости и сложностей с дальнейшим обновлением. Выход нашелся в использовании переменной «PORTAGE_BINPKG_TAR_OPTS». Благодаря ей, появилась возможность задействовать опции «--exclude» и «--exclude-from» архиватора «tar».
Да, я знаком с переменной «PKG_INSTALL_MASK» в «/etc/make.conf», но ее использование показалось мне менее удобным, хотя ничто не мешает использовать и ее.
Создадим директорию «/etc/portage/env» и файл «/etc/portage/bashrc».
# mkdir /etc/portage/env
# nano /etc/portage/bashrc
bashrc# Search and exclude fake '.so' in '/usr/lib', but it is needed only linkage
EXCLUDELD=$(cat "${EBUILD}"|sed -e 's/^[ \t]*//'| \
sed -n '/^gen_usr_ldscript/p'| \
sed -e 's/^gen_usr_ldscript[ \t]*//;s/-a[ \t]*//;s/\( \)\+/\n/g')
EXCLUDELD=$(echo "${EXCLUDELD}"| \
sed -e 's/^lib//;s/\.so.*//;s/^/--exclude \*\/usr\/lib\/lib/;s/$/.so/')
[ -n "${EXCLUDELD}" ] && \
PORTAGE_BINPKG_TAR_OPTS="${EXCLUDELD} ${PORTAGE_BINPKG_TAR_OPTS}"
# Per package exclude list
[ -f "/etc/portage/env/${CATEGORY}/${PN}.exclude" ] && \
PORTAGE_BINPKG_TAR_OPTS="${PORTAGE_BINPKG_TAR_OPTS} -X \
/etc/portage/env/${CATEGORY}/${PN}.exclude"
С помощью этого файла можно вырезать из состава бинарного пакета все «лишнее». В данном случае у всех пакетов проверяется наличие «поддельных» файлов библиотек в «/usr/lib» необходимых только для процесса линковки, но бесполезных для работы. Такие файлы игнорируются. Так же появляется возможность задавать индивидуальную маску для файлов, которые не будут попадать в архив бинарного пакета. Например, в пакеты, необходимые только для сборки, файлы вообще попадать не будут, только метаданные.
К примеру, если выполнить нижеприведенные действия, то получится бинарный пакет «sys-devel/make», содержащий метаданные, но не устанавливающий в систему никаких файлов. То есть пакет - «заглушка», просто удовлетворяющий зависимости.
# echo '*' >/etc/portage/env/sys-devel/make.exclude
# emerge make -1
Для текущей установки потребуются файлы с индивидуальными масками для пакетов. Я сделал небольшие наброски для базовой системы и собрал в архив. Скачиваем его и распаковываем.
# wget http://mrcat.ru/download/chroot-install/packages.exclude.tar.bz2
# tar -xjvpf ./packages.exclude.tar.bz2 -C /etc/portage
# rm -f ./packages.exclude.tar.bz2
Таким образом на конечном устройстве будут и зависимости удовлетворены, и файлов, необходимых только для процесса сборки, не будет. Этим простым способом можно сильно сократить набор устанавливаемых файлов. Единственная сложность здесь - это долгий ручной поиск «ненужных» файлов в бинарных пакетах и заполнение файлов исключений. Но, я думаю, на это можно потратить один вечер и в дальнейшем просто пользоваться, изредка подправляя эти файлы по мере необходимости.
Пришло время первой сборки. Еще раз проверим все ли USE-флаги заданы верно и обновим «system».
# emerge system -ep
# emerge system -e
После обновления «system» нужно выполнить обновление файлов в «/etc». Это можно сделать с помошью утилиты «etc-update», предварительно настроив файл «/etc/etc-update.conf».
# nano /etc/etc-update.conf
Я изменяю только два параметра.
etc-update.confmode="1"
pager=""
Затем, как рекомендовано в этом файле, устанавливаем «dev-util/dialog».
# emerge dialog
Выполняем обновление «/etc».
# etc-update
Можно смело заменить все файлы на новые, за исключением «/etc/locale.gen».
Переключаем профиль «gcc». Посмотреть установленные профили можно следующей командой.
# gcc-config -l
У меня установилось «gcc-4.4.4», поэтому я выполняю следующее.
# gcc-config i686-pc-linux-gnu-4.4.4
# env-update && source /etc/profile
Затем просматриваем и чистим в системе ненужные пакеты.
# emerge --depclean -p
# emerge --depclean
Запустите поиск нарушенных зависимостей, предварительно установив набор утилит из пакета «app-portage/gentoolkit».
# emerge gentoolkit
# revdep-rebuild
Обновляем «world» новой версией «gcc».
# emerge world -e
Если необходимо, повторно выполните обновление «/etc» с помощью «etc-update».
# etc-update
Установим ряд системных пакетов. Это демон syslog, демон cron и загрузчик. Я выбрал для этого «app-admin/syslog-ng», «sys-process/cronie» и «sys-boot/grub».
# emerge syslog-ng cronie grub
Установим набор дополнительных пакетов. Я просто приведу примерный список.
# emerge logrotate sudo mc screen bind-tools dhcpcd telnet-bsd htop lsof clockspeed
Пока что этого будет достаточно.
Сборка ядра
У нас уже есть набор необходимых бинарных пакетов, но еще нет ядра. Посмотрим список доступных ядер.
# emerge --search '%-sources'
Мне подходит пакет «sys-kernel/gentoo-sources». Его я и буду устанавливать.
# emerge gentoo-sources
Чтобы не тратить много времени на просмотр всех опций ядра, для первого запуска можно воспользоваться готовым конфигурационным файлом, взятым из любого «LiveCD» на основе «GNU/Linux». Я предпочитаю использовать «SystemRescueCD».
Загружаемся с «LiveCD» и извлекаем конфигурацию ядра.
# cat /proc/config.gz | gunzip >/.config
После этого файл «.config» любым доступным способом переносим на наш компьютер, где ведется сборка, и копируем в «/usr/src/linux» в нашем chroot-окружении.
Выполняем конфигурацию ядра.
# cd /usr/src/linux
# sed -e "/CONFIG_INITRAMFS_SOURCE/d" -i .config
# make oldconfig
Позже придется не раз запускать «make menuconfig» для оптимального конфигурирования ядра с последующей компиляцией. Но пока что, для первого старта, этого достаточно.
Воспользуемся небольшим скриптом «makekernel.sh» для сборки, создания и установки пакета с бинарным ядром.
makekernel.sh#!/bin/bash
#
# Make kernel and modules
# Install into portage
# Build binary package
#
source "/usr/lib/portage/bin/isolated-functions.sh"
if [ ! -L "/usr/src/linux" ]; then
eerror "'/usr/src/linux' not a symlink"
exit 1
fi
TMPDIR=$(mktemp -u -d -p /tmp/ krn.XXXXXX)
KERNELLINK=$(readlink /usr/src/linux|sed -e 's/^linux-//')
KERNEL="/usr/src/linux-${KERNELLINK}"
if [ -d "${KERNEL}" ]; then
if [ ! -f "${KERNEL}/.config" ]; then
eerror "Kernel confiruration '.config' not found"
exit 1
fi
else
eerror "Kernel source directory not exist"
exit 1
fi
PREFIX="$(echo "${KERNELLINK}"|cut -d '-' -f2)"
PN="${PREFIX}-kernel"
PNFW="kernel-firmware"
PV=$(echo "${KERNELLINK}"|cut -d '-' -f1)
PR=$(echo "${KERNELLINK}"|cut -d '-' -f3)
[ -n "${PR}" ] && PR="-${PR}"
PVR="${PV}${PR}"
PF="${PN}-${PVR}"
PFFW="${PNFW}-${PVR}"
INSTALL="${TMPDIR}/sys-kernel/${PN}/files"
INSTALLFW="${TMPDIR}/sys-kernel/${PNFW}/files/lib"
eval $(portageq envvar -v PKGDIR)
if [ -z "${PKGDIR}" ]; then
eerror "Variable 'PKGDIR' not set in '/etc/make.conf'"
exit 1
fi
cd "${KERNEL}"
einfo "Preparing kernel and modules..."
if make bzImage modules EXTRAVERSION=-${PREFIX}; then
einfo "Install modules..."
INSTALL_MOD_PATH="${INSTALL}" make modules_install EXTRAVERSION=-${PREFIX}
else
eerror "Kernel compilation error!"
exit 1
fi
if [ -d "${INSTALL}/lib/modules" ]; then
einfo "Prepare environment..."
mkdir -p "${INSTALLFW}"
if [ -d "${INSTALL}/lib/firmware" ]; then
mv -f "${INSTALL}/lib/firmware" "${INSTALLFW}"
FWDEP=">=sys-kernel/kernel-firmware-${PVR}"
else
ewarn "Firmware not found."
FWDEP=""
fi
mkdir -p "${INSTALL}/boot"
cp "${KERNEL}/System.map" "${INSTALL}/boot/System.map-${PV}-${PREFIX}"
cp "${KERNEL}/arch/i386/boot/bzImage" "${INSTALL}/boot/kernel-${PV}-${PREFIX}"
rm -f "${INSTALL}/lib/modules/${PV}-${PREFIX}/build"
rm -f "${INSTALL}/lib/modules/${PV}-${PREFIX}/source"
cat > "${TMPDIR}/sys-kernel/${PN}/${PF}.ebuild" << EOF
# Copyright 1999-2009 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
inherit mount-boot
EAPI="2"
DESCRIPTION="Binary ${PVR} kernel and modules"
HOMEPAGE="http://mrcat.ru"
SRC_URI=""
LICENSE="GPL-2"
SLOT="${PV}"
KEYWORDS="~amd64 ~x86"
IUSE=""
RDEPEND="virtual/dev-manager ${FWDEP}"
pkg_setup() {
ewarn 'All modules from "/lib/modules/${PV}-${PREFIX}" removed'
ewarn 'Please, run "module-rebuild rebuild" after installation'
rm -rf /lib/modules/${PV}-${PREFIX}
}
src_install() {
insinto /
doins -r "\${FILESDIR}/boot"
doins -r "\${FILESDIR}/lib"
}
pkg_prerm() {
mount-boot_mount_boot_partition
}
EOF
cat > "${TMPDIR}/sys-kernel/${PNFW}/${PFFW}.ebuild" << EOF
# Copyright 1999-2009 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
EAPI="2"
DESCRIPTION="Binary ${PVR} kernel firmware"
HOMEPAGE="http://mrcat.ru"
SRC_URI=""
LICENSE="GPL-2"
SLOT="0"
KEYWORDS="~amd64 ~x86"
IUSE=""
RDEPEND="!sys-kernel/linux-firmware"
src_install() {
insinto /
doins -r "\${FILESDIR}/lib"
}
EOF
if [ -n "${FWDEP}" ]; then
einfo "Building kernel firmware..."
ebuild "${TMPDIR}/sys-kernel/${PNFW}/${PFFW}.ebuild" digest package
einfo "Install kernel firmware..."
[ -f "${PKGDIR}/sys-kernel/${PFFW}.tbz2" ] && emerge -1K "=sys-kernel/${PFFW}" || eerror "Kernel firmware not installed"
fi
einfo "Building binary kernel..."
ebuild "${TMPDIR}/sys-kernel/${PN}/${PF}.ebuild" digest package
einfo "Install binary kernel..."
[ -f "${PKGDIR}/sys-kernel/${PF}.tbz2" ] && emerge -K "=sys-kernel/${PF}" || eerror "Kernel not installed"
rm -rf "${TMPDIR}"
else
eerror "Kernel compilation error!"
exit 1
fi
Сохраним скрипт в «/usr/src/makekernel.sh» и выполним.
# chmod 755 /usr/src/makekernel.sh
# /usr/src/makekernel.sh
Если все прошло успешно, то в нашем chroot-окружении появится два установленных пакета. Например, если установлен пакет «sys-kernel/gentoo-sources», то появятся пакеты «sys-kernel/gentoo-kernel» и, если есть в том необходимость, «sys-kernel/kernel-firmware». Таким образом, никогда не придется выполнять сборку ядра на конечном устройстве, если у нас есть бинарные пакеты с ядром, которые можно установить, как и любые другие, используя пакетный менеджер.
Подготовка конечного устройства к установке
В моем случае, осталось настроить http-сервер для доступа к директории «/srv/cfarm/binhost» из локальной сети. Для этого я использую сервер «Apache», установленный на этом же компьютере.
Не используйте ftp-сервер для доступа к бинарным пакетам! Последние версии пакетного менеджера «portage» работают с проблемами по ftp-протоколу.
Настало время установки «Gentoo GNU/Linux» на конечное устройство. Для этого необходимо иметь загруженную систему на конечном устройстве с работающей системой «Portage».
Для этих целей я использую все тот же «SystemRescueCD». Нужно выполнить загрузку с iso-образа данного «LiveCD» на конечном устройстве. О том, как это сделать, подробно рассказано на официальной странице проекта в разделе документации.
Я буду производить установку на виртуальной машине, созданной в «VirtualBox» с размером виртуального диска 1Gb и размером оперативной памяти 128Mb. Этого более чем достаточно для установки системы. Так «много» оперативной памяти необходимо только для установки системы. При хорошей оптимизации ядра, система будет непринужденно работать и с 64Mb RAM.
Выполнив загрузку с «LiveCD», зададим пароль суперпользователя «root» и настроим сеть, чтобы иметь возможность подключиться к системе по «ssh» и работать с привычным и удобным терминалом.
# passwd
# net-setup eth0
Для удобства установки полезно использовать утилиту «screen», которая дает возможность быстро переключаться между сессиями.
Выполним синхронизацию времени.
# ntpdate pool.ntp.org
# hwclock -uw
Разбиваем жесткие диски на разделы. У меня в тестовой виртуальной машине он всего один.
# cfdisk /dev/sda
Первый раздел «/dev/sda1» - загрузочный, размером 32 Mb. Далее идет раздел подкачки «/dev/sda2» размером 256 Mb. Все остальное идет под корневой раздел «/dev/sda3».
В результате вывод команды «fdisk -l» будет выглядеть как показано ниже.
Disk /dev/sda: 1073 MB, 1073741824 bytes
255 heads, 63 sectors/track, 130 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
Device Boot Start End Blocks Id System
/dev/sda1 * 1 4 32098+ 83 Linux
/dev/sda2 5 35 249007+ 83 Linux
/dev/sda3 36 130 763087+ 83 Linux
Форматируем разделы и активируем раздел подкачки.
# mkfs.ext2 /dev/sda1
# mkfs.ext3 /dev/sda3
# mkswap /dev/sda2
# swapon /dev/sda2
Создаем необходимые директории и монтируем разделы.
# mkdir /mnt/test
# mount /dev/sda3 /mnt/test
# mkdir -p /mnt/test/{boot,dev,home,mnt,proc,root,sys,var/portage/portage,var/portage/packages,/etc/portage/env,var/tmp}
# chmod 700 /mnt/test/root
# touch /mnt/test/boot/.keep
# mount /dev/sda1 /mnt/test/boot
Создадим два устройства, без которых процесс загрузки будет проблематичным.
# mknod -m 600 /mnt/test/dev/console c 5 1
# mknod -m 666 /mnt/test/dev/null c 1 3
Следующий этап наиболее интересен. Нет необходимости снова разворачивать «Stage3», как рекомендует руководство. Мы уже имеем набор бинарных пакетов, а на данном «LiveCD» - установленный менеджер пакетов «portage». Так что нам мешает просто установить бинарные пакеты в нужное нам место?
Установка бинарных пакетов
Приступим. Необходимо удалить базу данных установленных пакетов c «LiveCD», иначе «portage» будет пытаться обновить в ней информацию, что затянется надолго, а ждать не хочется.
# rm -rf /var/db/pkg/*
Настроим файл «/etc/make.conf» системы на «LiveCD» для того, чтобы «emerge» мог видеть наш репозиторий с бинарными пакетами. Для этого изменим файл «/etc/make.conf».
# nano /etc/make.conf
...
PORTDIR="/mnt/test/var/portage/portage"
PORTAGE_RSYNC_EXTRA_OPTS="--progress --delete-excluded --exclude-from=/etc/portage/portage.exclude"
PORTAGE_BINHOST="http://packages.myhost.cxm/test"
Создадим файл «/etc/portage/portage.exclude».
# nano /etc/portage/portage.exclude
portage.exclude+ /profiles
- *.mask
- /*
Я планирую хранить на конечном устройстве остатки дерева «Portage» в «/var/portage/portage». Поэтому сразу задаю соответствующее значение переменной «PORTDIR» в файле «/etc/make.conf»
Выполним синхронизацию.
# emerge --sync
Настроим «portage» для установки бинарных пакетов на конечное устройство.
Создадим файл «/mnt/test/etc/make.conf».
# nano /mnt/test/etc/make.conf
make.confCHOST="i686-pc-linux-gnu"
ACCEPT_KEYWORDS="~x86"
FEATURES="-parallel-fetch getbinpkg nodoc noman noinfo"
EMERGE_DEFAULT_OPTS="--alphabetical --verbose --nospinner"
PORTAGE_RSYNC_EXTRA_OPTS="--delete-excluded --exclude-from=/etc/portage/portage.exclude"
PORTAGE_BINHOST="http://packages.myhost.cxm/test"
PORTDIR="/var/portage/portage"
PKGDIR="/var/portage/packages"
LINGUAS="ru"
Обратите внимание на значение переменной PORTAGE_BINHOST. Путь должен указывать на месторасположение бинарных пакетов на сервере.
Копируем файлы «/etc/portage/portage.exclude» и «/etc/make.globals» с «LiveCD».
# cp -f /etc/portage/portage.exclude /mnt/test/etc/portage
# cp -fH /etc/make.globals /mnt/test/etc
При установке дополнительных модулей ядра, «portage» будет искать исходные тексты ядра, а их не будет. Так же нет необходимости сохранять файлы бинарных пакетов на конечном устройстве.
Для решения этих задач создадим файл «/mnt/test/etc/portage/bashrc».
# nano /mnt/test/etc/portage/bashrc
bashrclinux-mod_pkg_setup() {
debug-print-function ${FUNCNAME} $*
strip_modulenames;
set_kvobj;
}
update_depmod() {
debug-print-function ${FUNCNAME} $*
# if we haven't determined the version yet, we need too.
get_version;
ebegin "Updating module dependencies ${KV_FULL}"
depmod -a -b ${ROOT} -r ${KV_FULL}
eend $?
}
post_pkg_postinst() {
rm -f "${PORTAGE_BINPKG_FILE}"
[ ! "$(ls -A "${PKGDIR}/${CATEGORY}")" ] && \
rm -rf "${PKGDIR}/${CATEGORY}"
rm -f "${PKGDIR}/Packages"
}
Установим профиль системы, предварительно просмотрев их список.
# eselect profile list
# ln -s ../var/portage/portage/profiles/default/linux/x86/10.0 /mnt/test/etc/make.profile
Так же, заранее создадим файл со списком локалей, как мы делали это при сборке в chroot-окружении.
# nano /mnt/test/etc/locale.gen
locale.genen_US.UTF-8 UTF-8
ru_RU.UTF-8 UTF-8
ru_RU.KOI8-R KOI8-R
ru_RU.CP1251 CP1251
ru_RU.IBM866 IBM866
Зададим временную зону.
# echo 'Europe/Moscow' >/mnt/test/etc/timezone
Скопируем файл «/etc/resolv.conf» в будущее chroot-окружение.
# cp -f /etc/resolv.conf /mnt/test/etc
Почти все готово для начала установки бинарных пакетов на диск. Осталось установить несколько заглушек для пакетов, которые желают что либо скомпилировать или произвести другие действия с файлами, которых не будет в системе. Я подготовил небольшой набор таких файлов.
# wget http://mrcat.ru/download/chroot-install/eclass.patches.tar.bz2
# tar -xjvpf ./eclass.patches.tar.bz2 -C /mnt/test/etc/portage
# rm -f ./eclass.patches.tar.bz2
Теперь подготовим окружение и начнем установку бинарных пакетов на диск. Нет необходимости ставить «system», достаточно сразу поставить «world».
# mkdir -p /var/portage/packages
# mount -o bind /mnt/test/var/portage/packages /var/portage/packages
# mount -o bind /mnt/test/var/tmp /var/tmp
# export ROOT="/mnt/test"
# export PORTAGE_CONFIGROOT="/mnt/test"
# emerge world -e
Установка дополнительных пакетов и настройка
Подготовим chroot-окружение для дальнейшей установки и перейдем в него.
# mount -o bind /dev /mnt/test/dev
# mount -o bind /dev/pts /mnt/test/dev/pts
# mount -t proc proc /mnt/test/proc
# chroot /mnt/test /bin/bash
# unset ROOT
# unset PORTAGE_CONFIGROOT
# eselect python set 1
# env-update && source /etc/profile
Сразу же выполним генерацию локалей, заданных в файле «/etc/locale.gen».
# locale-gen
Если устанавливался пакет «sys-libs/cracklib», то нужно выполнить следующее.
# create-cracklib-dict /usr/share/dict/* >/dev/null
Переустановим пакет «net-misc/openssh», так как он создает для своей работы пользователя «sshd» и без него не запустится.
# emerge openssh -1
Установим дополнительные пакеты.
# emerge logrotate sudo syslog-ng mc screen \
gentoolkit dialog bind-tools dhcpcd telnet-bsd grub \
cronie htop lsof clockspeed
Подправим, как делали раньше, файл «/etc/etc-update.conf».
# nano /etc/etc-update.conf
etc-update.confmode="1"
pager=""
Обновим «/etc».
# etc-update
Проверим систему на наличие «битых» библиотек.
# revdep-rebuild -p
Если «revdep-rebuild» показывает наличие недостающих библиотек, значит при сборке пакетов, в которых должны присутствовать эти библиотеки, их не обнаружено. Видимо, перестарались с исключением «мусора» из этих пакетов.
Установим пакет с ядром, которое собрали ранее.
# emerge gentoo-kernel
Пришло время установить загрузчик. Создадим файл «/boot/grub/grub.conf«
# nano /boot/grub/grub.conf
grub.conftimeout 5
default 0
# Gentoo
title=Gentoo
root (hd0,0)
kernel /kernel-2.6.33-gentoo root=/dev/sda3
# Reboot
title Reboot
reboot
# Shutdown
title Shutdown
halt
Создадим файл «/etc/mtab», выполнив следующее.
# cat /proc/mounts >/etc/mtab
Выполним установку «grub» в «MBR».
# grub-install /dev/sda
На этом установка загрузчика закончена.
Добавим необходимые сервисы в автозагрузку.
# rc-update add consolefont boot
# rc-update add cronie default
# rc-update add syslog-ng default
# rc-update add sshd default
Зададим пароль суперпользователя «root» и добавим ему в домашнюю директорию файлы из «/etc/skel«
# passwd
# cp -rf /etc/skel/. /root
Создадим учетную запись пользователя, под которой будем работать, зададим пароль и обеспечим запуск программ с правами суперпользователя для возможности администрирования системы. Я добавлю пользователя «mrcat».
# useradd -g users -G wheel,audio,cdrom,video,cdrw -m mrcat
# chmod 700 /home/mrcat
# passwd mrcat
# echo 'mrcat ALL=(ALL) ALL'>>/etc/sudoers
Зададим локаль по умолчанию.
# echo -e 'LANG="ru_RU.UTF-8"\nLC_ALL="ru_RU.UTF-8"' >/etc/env.d/02locale
Изменим файл «/etc/fstab».
# nano /etc/fstab
fstab/dev/sda1 /boot ext2 noauto,noatime 1 2
/dev/sda3 / ext3 noatime 0 1
/dev/sda2 none swap sw 0 0
shm /dev/shm tmpfs nodev,nosuid,noexec 0 0
Далее приступим к настройке различных приложений.
Поскольку у меня установлен пакет «app-shells/bash-completion», то я выполняю следующее.
# eselect bashcomp enable --global base
Так же я запрещаю заходить по протоколу «SSH» пользователю «root», редактируя файл «/etc/ssh/sshd_config».
# sed -e 's/^#PermitRootLogin yes/PermitRootLogin no/' -i /etc/ssh/sshd_config
Изменим файл «/etc/conf.d/consolefont».
# nano /etc/conf.d/consolefont
consolefontconsolefont="cyr-sun16"
Изменим файл «/etc/conf.d/hostname».
# nano /etc/conf.d/hostname
hostnamehostname="test"
Изменим файл «/etc/conf.d/hwclock».
# nano /etc/conf.d/hwclock
hwclockclock_systohc="YES"
Изменим файл «/etc/conf.d/keymaps».
# nano /etc/conf.d/keymaps
keymapskeymap="ruwin_ctrl-UTF-8"
Настроим сеть. Создадим символическую ссылку.
# ln -s net.lo /etc/init.d/net.eth0
Изменим файл «/etc/conf.d/net».
# nano /etc/conf.d/net
Для загрузки с использованием «DHCP», как в моем случае, добавим следующее.
netmodules_eth0="dhcpcd"
config_eth0="dhcp"
dhcpcd_eth0="-b -L"
Изменим файл «/etc/rc.conf».
# nano /etc/rc.conf
Раскомментируем следующие строки.
rc.confrc_interactive="YES"
rc_depend_strict="NO"
rc_hotplug="*"
unicode="YES"
Возвращаемся из choot-окружения в основную систему.
Первый запуск
Все готово для первой загрузки во вновь установленную систему. Для этого я выключаю виртуальную машину в «VirtualBox», убираю автозагрузку с образа компакт-диска и снова включаю.
Если после перезагрузки не работает локализация, то перезагрузитесь еще раз - проблема должна исчезнуть.
Если все было сделано правильно, система должна загрузиться без ошибок.
Посмотрим, сколько места система заняла на диске. У меня получился вот такой замечательный результат.
# df -h
Filesystem Size Used Avail Use% Mounted on
rootfs 734M 239M 459M 35% /
/dev/root 734M 239M 459M 35% /
devtmpfs 56M 160K 56M 1% /dev
rc-svcdir 1.0M 44K 980K 5% /lib/rc/init.d
shm 57M 0 57M 0% /dev/shm
Оказывается, «Gentoo GNU/Linux» можно сделать совсем нетребовательным к дисковым ресурсам. Даже не требуется установка утилиты «localepurge» для удаления неиспользуемых локалей - их уже и так нет.
Обновление системы
Далее я расскажу, как обновлять такую систему. Если посмотреть, то почти все команды «emerge» идут сначала с опцией «-p (--pretend)», потом без нее. Так удобнее делать для того, чтобы перед обновлением или установкой видеть, что будет происходить и иметь возможность сначала изменить конфигурацию пакетного менеджера «portage».
Все настройки «portage» и USE-флаги меняются только на компьютере, где происходит сборка. На конечном устройстве конфигурация менеджера пакетов «portage» остается неизменной.
Это очень удобно, так как избавляет от необходимости писать одни и те же настройки дважды.
Для обновления системы на компьютере, где производилась сборка, я использую небольшой скрипт «ecleaner», который заменяет собой команду «eclean -d packages» и дополнительно чистит файл «Packages», который расположен в директории бинарных пакетов, от лишних записей, так как «portage» этого почему-то не делает.
ecleaner#!/bin/bash
source "/usr/lib/portage/bin/isolated-functions.sh"
source "/etc/make.conf"
# Clean unused packages
/usr/bin/qpkg -E
# Clean unused blocks
einfo "Cleaning unused blocks..."
PKGLIST=$(cat "${PKGDIR}/Packages"|grep 'CPV:'|sed -e 's/CPV: //')
for CPV in ${PKGLIST}; do
if [ ! -f "${PKGDIR}/${CPV}.tbz2" ]; then
sed -e "/^CPV: ${CPV//\//\\/}$/,/^$/d" -i "${PKGDIR}/Packages"
ewarn "${CPV}"
fi
done
Сохраним скрипт в «/usr/local/sbin/ecleaner» и сделаем его исполняемым.
# chmod 755 /usr/local/sbin/ecleaner
Действия при регулярном обновлении мира.
На компьютере, где производится сборка бинарных пакетов, выполняем следующее.
# emerge --sync
# emerge world -uDNp
# emerge world -uDN
# etc-update
# emerge --depclean -p
# emerge --depclean
# revdep-rebuild
# ecleaner
На конечном устройстве, если отсутствует дерево «Portage», при выполнении команды «emerge», у последней перестает работать опция «--newuse». Поэтому, если изменить USE-флаги, и потом на конечном устройстве выполнить «emerge world -uDNp», то для пакетов с измененными USE-флагами обновление выполняться не будет.
Поэтому пойдем на небольшую хитрость и обновление мира будем выполнять скриптом «eworld».
eworld#!/bin/bash
UPDLIST=$(emerge -eqp --color=n world | grep -e '\[binary' \
| sed -n '/^\[.*U.*\].*\//p;/^\[.*S.*\].*\//p;/\*/p;/\%/p' \
| cut -d ']' -f2 | sed -e 's/^\s/=/' | cut -d' ' -f1| uniq)
if [ -z "${UPDLIST}" ]; then
echo "Nothing to do."
else
emerge -1 ${UPDLIST} $*
fi
Сохраним скрипт в «/usr/local/sbin/eworld» на конечном устройстве и выполним следующее.
# chmod 755 /usr/local/sbin/eworld
Теперь произведем обновление мира на конечном устройстве.
# emerge --sync
# eworld -p
# eworld
# etc-update
# emerge --depclean -p
# emerge --depclean
Действия при установке нового пакета.
На компьютере, где производится сборка бинарных пакетов, выполняем следующее.
# emerge foo -p
# emerge foo
На конечном устройстве - следующее.
# emerge foo -p
# emerge foo
Действия при удалении пакета.
На компьютере, где производится сборка бинарных пакетов, выполняем следующее.
# emerge -С foo
# emerge --depclean -p
# emerge --depclean
# revdep-rebuild
# ecleaner
На конечном устройстве -следующее.
# emerge -C foo
# emerge --depclean -p
# emerge --depclean
# revdep-rebuild
Действия при обновлении ядра. Допустим, у нас было установлено ядро «gentoo-sources-2.6.33-r1», а при обновлении мира установилось еще и ядро «gentoo-sources-2.6.33-r2».
Действия на компьютере, где производится сборка бинарных пакетов.
# eselect kernel list
# eselect kernel set linux-2.6.33-gentoo-r2
# cp -f /usr/src/linux-2.6.33-gentoo-r1/.config /usr/src/linux
# cd /usr/src/linux && make oldconfig
# /usr/src/makekernel.sh
# ecleaner
# rm -rf /usr/src/linux-2.6.33-gentoo-r1
# rm -rf /lib/modules/2.6.33-gentoo-r1
Если устанавливались дополнительные модули ядра, то для их обновления удобно использовать утилиту «module-rebuild». Установим ее и выполним.
# emerge module-rebuild
# module-rebuild rebuild
Выполним на конечном устройстве.
# emerge gentoo-kernel
# emerge --depclean -p
# emerge --depclean
Так же, если устанавливались дополнительные модули, нужно выполнить следующее.
# module-rebuild rebuild
Затем нужно изменить конфигурационный файл загрузчика «/boot/grub/grub.conf», чтобы включить загрузку с нового ядра.
# nano /boot/grub/grub.conf
Заключение
Как видно из статьи, можно подойти к процессу установки «Gentoo GNU/Linux» более оригинально, нежели рекомендует официальное руководство. Можно заставить работать самый различный класс устройств с данным дистрибутивом, применяя метод, описанный в статье.
По данной схеме уже достаточно продолжительное время работают несколько серверов и рабочих станций. Выигрыш в использовании очевиден - оптимизация пакетов для конкретного процессора, пакеты собраны только с необходимыми USE-флагами, экономия дискового пространства и ресурсы компьютеров используются по назначению, а не для процесса компиляции.