2010
Сборка ядра в Gentoo GNU/Linux отдельно от исходников
После установки новых исходных текстов ядра и удаления старых через «portage» в «Gentoo GNU/Linux» в директории «/usr/src» остается «мусор» после сборки старого ядра. Приходится его удалять вручную, что просто надоело. Я решил бороться с этим явлением, выполняя сборку ядра отдельно от исходных текстов. В результате, при удалении старых исходных текстов ядра через «portage», в «/usr/src» больше не остается ничего лишнего.
Так же мне захотелось иметь бинарный пакет с откомпилированным ядром, чтобы не выполнять компиляцию ядра на другом компьютере, где это неудобно делать. Например на нетбуке.
Весь этот процесс я попробовал максимально упростить с помощью небольшого набора скриптов.
Эта заметка является дополнением предыдущей большой статьи про установку «Gentoo GNU/Linux» из бинарных пакетов.
Сначала надо определиться, в какой директории будут создаваться временные файлы при сборке ядра. Поскольку у меня вся работа с пакетным менеджером перенесена в «/var/portage», то пусть и ядро будет собираться там же в «/var/portage/kernel». Создадим эту директорию.
# mkdir -p /var/portage/kernel
Здесь будут находиться файлы, создающиеся во время сборки ядра. Они будут разложены по отдельным директориям. Например, для пакета «sys-kernel/gentoo-sources-2.6.36-r1» будет необходима директория «/var/portage/kernel/kernel-2.6.36-gentoo-r1». В нее в дальнейшем нужно будет скопировать файл «.config» от старого ядра.
Для того, чтобы не создавать вручную при установке свежих исходных текстов ядра новую директорию в «/var/portage/kernel», возложим это на плечи пакетного менеджера. Для этого создадим директорию «/etc/portage/env/sys-kernel».
# mkdir -p /etc/portage/env/sys-kernel
Если выполняется установка, например, пакета «gentoo-sources», создадим файл «gentoo-sources» в «/etc/portage/env/sys-kernel» следующего содержания.
/etc/portage/env/sys-kernel/gentoo-sourcespost_src_unpack() {
# Remove "-rXX" from EXTRAVERSION
sed -i -e 's/\(^EXTRAVERSION = .*\)-r.*$/\1/' "${S}/Makefile"
}
post_pkg_postinst() {
# Specify a directory for temporary kernel files.
KBUILD_DIR="/var/portage/kernel"
[ "${PR}" != "r0" ] && PR="-${PR}" || PR=""
KBUILD_OUTPUT="${KBUILD_DIR}/kernel-${PV}-${PN/-sources/}${PR}"
[ ! -d "${KBUILD_OUTPUT}" ] && mkdir -p "${KBUILD_OUTPUT}"
# If you want to copy the current kernel configuration, uncomment the following line.
# [ -f /proc/config.gz ] && [ ! -f "${KBUILD_OUTPUT}/.config" ] && gzip -cd /proc/config.gz >"${KBUILD_OUTPUT}/.config"
}
Измените в нем значение переменной «KBUILD_DIR», если это необходимо. Так же можно раскомментировать предпоследнюю строку скрипта, если сборка ведется не в «chroot», а для этого же самого компьютера и в текущем запущенном ядре была включена опция «CONFIG_IKCONFIG_PROC». Тогда текущая конфигурация ядра будет скопирована во вновь созданную директорию.
Следует добавить в файл «/etc/portage/bashrc» проверку на имя устанавливаемого пакета. И если это имя заканчивается на «…modules» или «…addons», то глобально устанавливать переменную «KBUILD_OUTPUT». Как и ранее, можно заменить «/var/portage/kernel» на что-либо свое.
/etc/portage/bashrcif [[ ${PN} =~ (modules|addons)$ ]]; then
export KBUILD_OUTPUT="/var/portage/kernel/kernel-$(readlink /usr/src/linux|sed -e 's/^linux-//')"
fi
Если этого не сделать, то дополнительные модули ядра устанавливаться не будут!
Поместим нижеприведенные четыре скрипта в «/var/portage/kernel».
/var/portage/kernel/makekernel.sh#!/bin/bash
#
# Make kernel and modules
# Install into portage
# Build binary package
#
source $(dirname $(readlink -f $0))/lib.sh
prepare
TMPDIR=$(mktemp -u -d -p /tmp/ krn.XXXXXX)
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; then
einfo "Install modules..."
INSTALL_MOD_PATH="${INSTALL}" make modules_install
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 "${KBUILD_OUTPUT}/System.map" "${INSTALL}/boot/System.map-${PV}-${PREFIX}"
cp "${KBUILD_OUTPUT}/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-2010 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-2010 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
/var/portage/kernel/makemenuconfig.sh#!/bin/bash
#
# Run 'make menuconfig'
#
source $(dirname $(readlink -f $0))/lib.sh
prepare
cd "${KERNEL}"
make menuconfig
/var/portage/kernel/makeoldconfig.sh#!/bin/bash
#
# Run 'make oldconfig'
#
source $(dirname $(readlink -f $0))/lib.sh
prepare
cd "${KERNEL}"
make oldconfig
/var/portage/kernel/lib.sh#!/bin/bash
# Specify a directory for temporary kernel files.
KBUILD_DIR="/var/portage/kernel"
prepare () {
source "/usr/lib/portage/bin/isolated-functions.sh"
if [ ! -L "/usr/src/linux" ]; then
eerror "'/usr/src/linux' not a symlink"
exit 1
fi
KERNELLINK=$(readlink /usr/src/linux|sed -e 's/^linux-//')
KERNEL="/usr/src/linux-${KERNELLINK}"
export KBUILD_OUTPUT="${KBUILD_DIR}/kernel-${KERNELLINK}"
if [ -d "${KBUILD_OUTPUT}" ]; then
if [ ! -f "${KBUILD_OUTPUT}/.config" ]; then
eerror "Kernel confiruration '${KBUILD_OUTPUT}/.config' not found"
exit 1
fi
else
eerror "Kernel binary directory '${KBUILD_OUTPUT}' not exist"
exit 1
fi
}
Все файлы одним архивом можно загрузить тут.
В файле «lib.sh» можно изменить значение переменной «KBUILD_DIR», если это необходимо.
Сделаем скрипты исполняемыми.
# chmod 755 /var/portage/kernel/makekernel.sh
# chmod 755 /var/portage/kernel/makemenuconfig.sh
# chmod 755 /var/portage/kernel/makeoldconfig.sh
Порядок работы со всем этим хозяйством следующий. Допустим, необходимо установить свежее ядро «sys-kernel/gentoo-sources-2.6.36-r1». После установки должна появится директория «/var/portage/kernel/kernel-2.6.36-gentoo-r1» и, если было задано, с файлом «.config» от текущего работающего ядра. Иначе скопируйте файл «.config» в «/var/portage/kernel/kernel-2.6.36-gentoo-r1» вручную от предыдущего ядра.
Далее с помощью «eselect kernel» или вручную меняем ссылку «/usr/src/linux» на директорию с новыми исходными текстами ядра. После этого выполняем скрипт «makeoldconfig.sh». При этом формируется конфигурация для нового ядра. Потом, если необходимо, выполняем «makemenuconfig.sh» для корректировки конфигурации. И в заключение - «makekernel.sh», в результате работы которого будет собрано новое ядро, создан и установлен бинарный пакет «sys-kernel/gentoo-kernel-2.6.31-r1» с новым ядром.
Я не стал учитывать номер ревизии при установке бинарного пакета с ядром. Думаю так будет проще при обновлении той же самой версии ядра, только другой ревизии. Например, модули ядра версии «2.6.36-r1» будут устанавливаться в «/lib/modules/2.6.36-gentoo».
Данный набор скриптов помог мне упростить процесс обновления ядра в «Gentoo GNU/Linux». Надеюсь что поможет и вам, если вы собираете ядро вручную.