Necesito compilar un núcleo personalizado

Created by RalphAngenendt. Currently maintained by AlanBartlett and AkemiYagi.

<<TableOfContents: execution failed [Argument "maxdepth" must be an integer value, not "[1]"] (see also the log)>>

Hay dos maneras de compilar un núcleo personalizado para CentOS. Una es compilar un núcleo con opciones personalizadas a partir de los fuentes de CentOS y la otra es compilar un núcleo oficial usando los fuentes obtenidos del Linux Kernel Archive (Archivo del Núcleo Linux).

Este tutorial cubrirá la compilación de un núcleo a partir de los fuentes de CentOS con nuestras propias opciones o modificaciones. Está escrito principalmente para CentOS-5. Busque las notas con el signo <!> para obtener información sobre la compilación de otras versiones de núcleos CentOS.

(Si desea compilar un núcleo oficial, no siga el documento Cómo Compilar Un Kernel (How To Compile A Kernel) Ese sitio no se recomienda, ya que detalla la compilación como usuario root, lo cual es un procedimiento inseguro y básicamente defectuoso. Vea Building Source RPM as non-root under CentOS para conocer el razonamiento detallado. Una buena referencia para compilar un kernel oficial es el libro Linux Kernel in a Nutshell.)

Estas acciones son para su uso personal. Los núcleos personalizados no están soportados por el equipo de desarrollo, ya que ellos no tienen control sobre su ambiente de compilación, las opciones escogidas, etc. Si elige compilar su propio núcleo, usted será el responsable de seguir manteniéndolo en caso de nuevas actualizaciones de seguridad, nuevas entregas, y cualquier otro escenario posible que pueda requerir tal mantenimiento.


1. Preparando la compilación

Para poder compilar un núcleo, necesitará instalar los siguientes paquetes:

Si tiene parches del núcleo que añadir, cópielos ahora al directorio SOURCES.

2. Configurando el núcleo

<!> Si está compilando un núcleo de CentOS-4, reemplace 2.6.18 con 2.6.9 cada vez que aparezca en el resto del tutorial y omita el componente ".`uname -m`" del nombre de los directorios en esta sección.

ArtWork/WikiDesign/icon-admonition-info.png

Si no piensa modificar el archivo de configuración del núcleo que viene con la distribución, puede omitir esta sección, siempre y cuando ejecute el equivalente del paso final:

[usuario@host] $ cp ~/rpmbuild/BUILD/kernel-2.6.18/linux-2.6.18.{{{`uname -m`/configs/* ~/rpmbuild/SOURCES}}}

Con la raíz de compilación establecida correctamente, es el momento de modificar la configuración del núcleo. Cambie directorio a ~/rpmbuild/BUILD/kernel-2.6.18/linux-2.6.18.`uname -m`/ y copie en este directorio, con el nombre .config, uno de dos archivos:

Vea el ejemplo siguiente:

[usuario@host]$ cd ~/rpmbuild/BUILD/kernel-2.6.18/linux-2.6.18.`uname -m`

O bien:

[usuario@host]$ cp configs/kernel-2.6.18-`uname -m`[-type].config .config

o bien:

[usuario@host]$ cp /boot/config-`uname -r` .config

Primero ejecute make oldconfig. Ahora deberá correr, o bien make menuconfig, make gconfig o make xconfig para personalizar la configuración del núcleo. Una vez terminada, recuerde grabar los cambios a la configuración.

ArtWork/WikiDesign/icon-admonition-info.png

Si ha instalado los fuentes completos del núcleo para compilar un módulo del núcleo, en este punto debe detenerse. Ahora por favor diríjase al tutorial Compilando módulos para el núcleo.

A continuación, agregue una línea que contenga, como comentario, el equivalente de la plataforma de hardware al tope del archivo de configuración (éste es el valor que devuelve el comando uname -i) antes de volver a copiarlo en el directorio configs/. Este valor será i386 para la arquitectura de 32 bits, o x86_64 para la arquitectura de 64 bits. Necesita estar precedido por un signo de comentario (#) y debe ser la primera línea del archivo. Nótese que debe haber un espacio entre el símbolo numeral y el descriptor de la plataforma de hardware. <!> Este paso no se requiere para los núcleos de CentOS-4.

Es decir, como primera línea del archivo .config, agregue, o bien:

# i386

- o bien -

# x86_64

Copie ahora el archivo .config de nuevo al directorio configs/. Esto es básicamente el opuesto del comando de copia realizado anteriormente:

[usuario@host]$ cp .config configs/kernel-2.6.18-`uname -m`[-type].config

El paso final es copiar el contenido completo del directorio configs/ al directorio ~/rpmbuild/SOURCES/.

[usuario@host]$ cp configs/* ~/rpmbuild/SOURCES

3. La ABI del núcleo

Una característica del núcleo de CentOS es que su ABI (interfaz binaria de aplicaciones) se preservará durante toda la vida del producto, y una ventaja de tener una kABI (ABI del núcleo) consistente es que se pueden compilar módulos externos independientes de la versión del núcleo. Por lo tanto, no necesitan ser recompilados para cada nuevo núcleo que se libera. Esta es la base del paquete de seguimiento de kABI kmod: proveer, por ejemplo, drivers actualizados de dispositivos y otro soporte del sistema de archivos.

Para mantener esta consistencia de ABI, la ABI original del núcleo fue grabada y almacenada en un archivo. Este archivo se usa durante el paso de verificación de kABI para cada nuevo núcleo que se compila. Si el núcleo nuevo ha sido configurado o modificado en forma tal que hay alguna variación respecto de la ABI publicada, la compilación fallará con un mensaje indicando que ha ocurrido una ruptura de kABI. El compilador del núcleo entonces tiene dos opciones: (a) reconfigurar el nuevo núcleo de manera que concuerde con la kABI publicada, y, por lo tanto, continuar disfrutando de los beneficios que provee una kABI consistente, o (b) deshabilitar la verificación de kABI durante el proceso de compilación. De las dos opciones, la primera es preferible pero, ocasionalmente, la última es la única manera de proceder.

Deshabilitar la verificación de ABI del núcleo consiste simplemente en proveer una opción y su argumento en la línea de comando de rpmbuild:

--without kabichk

O debería ser así de simple. Desafortunadamente, para todos los núcleos >= 2.6.18-92.el5, una modificación al archivo kabitool ha expuesto un error latente en el archivo de especificación del núcleo. Este error ha sido reconocido "arriba" (bz456765) y eventualmente será corregido, probablemente con la entrega de la actualización 6 (CentOS 5.6).

Hasta que ocurra dicha corrección, los compiladores de núcleos que necesiten deshabilitar la verificación de kABI deberán realizar dos pasos extra al editar el archivo de configuración de núcleo. Estos dos pasos se detallan claramente en la sección siguiente de este tutorial.

4. Modificando el archivo de especificación del núcleo

ArtWork/WikiDesign/icon-admonition-info.png

Los números de línea mencionados en esta sección se refieren al archivo de especificación del núcleo CentOS-5 actual únicamente.

Ahora necesitará modificar el archivo de especificación del núcleo.

[usuario@host]$ cd ~/rpmbuild/SPECS
[usuario@host SPECS]$ cp kernel-2.6.spec kernel-2.6.spec.distro
[usuario@host SPECS]$ vi kernel-2.6.spec

En la línea 73, la definición de buildid está comentada. Esta debe descomentarse y recibir un valor para evitar un conflicto con su núcleo actualmente instalado. Cambie la línea en forma similar al ejemplo más abajo:

%define buildid .your_identifier

ArtWork/WikiDesign/icon-admonition-info.png

No debe haber espacios entre el "%" y la palabra "define".

Con comienzo en la línea 8720 hay un bloque de código que debe ser comentado. Este bloque de código comienza con la frase #if a rhel kernel, apply the rhel config options. Comente las siguiente 25 líneas para compilar núcleos CentOS-5 personalizados ( <!> Este paso no se requiere para compilar núcleos personalizados CentOS-4.):

#if a rhel kernel, apply the rhel config options
#%if 0%{?rhel}
#  for i in %{all_arch_configs}
#  do
#    mv $i $i.tmp
#    $RPM_SOURCE_DIR/merge.pl $RPM_SOURCE_DIR/config-rhel-generic $i.tmp > $i
#    rm $i.tmp
#  done
#%ifarch x86_64 noarch
#  for i in kernel-%{kversion}-x86_64*.config
#  do
#    mv $i $i.tmp
#    $RPM_SOURCE_DIR/merge.pl $RPM_SOURCE_DIR/config-rhel-x86_64-generic $i.tmp > $i
#    rm $i.tmp
#  done
#%endif
#%ifarch ppc64 noarch
#  #CONFIG_FB_MATROX is disabled for rhel generic but needed for ppc64 rhel
#  for i in kernel-%{kversion}-ppc64.config
#  do
#    mv $i $i.tmp
#    $RPM_SOURCE_DIR/merge.pl $RPM_SOURCE_DIR/config-rhel-ppc64-generic $i.tmp > $i
#    rm $i.tmp
#  done
#%endif
#%endif

<!> Debido a errores en el archivo de especificación del núcleo (que aún deben ser corregidos "arriba"), deberá hacer las siguientes dos correcciones. Esto solamente se necesita cuando "se debe deshabilitar verificación kABI" con los núcleos >= 2.6.18-92.el5. Por favor vea la Sección 3 para mayores detalles.

Vaya a la línea 9096 donde verá un bloque de código que comienza con la frase # Create the kABI metadata for use in packing:

    # Create the kABI metadata for use in packaging
    echo "**** GENERATING kernel ABI metadata ****"
    gzip -c9 < Module.symvers > $RPM_BUILD_ROOT/boot/symvers-$KernelVer.gz
    chmod 0755 %_sourcedir/kabitool
    if [ ! -e $RPM_SOURCE_DIR/kabi_whitelist_%{_target_cpu}$Flavour ]; then
        echo "**** No KABI whitelist was available during build ****"
        %_sourcedir/kabitool -b $RPM_BUILD_ROOT/$DevelDir -k $KernelVer -l $RPM_BUILD_ROOT/kabi_whitelist
    else
        cp $RPM_SOURCE_DIR/kabi_whitelist_%{_target_cpu}$Flavour $RPM_BUILD_ROOT/kabi_whitelist
    fi
    rm -f %{_tmppath}/kernel-$KernelVer-kabideps
    %_sourcedir/kabitool -b . -d %{_tmppath}/kernel-$KernelVer-kabideps -k $KernelVer -w $RPM_BUILD_ROOT/kabi_whitelist

%if %{with_kabichk}
    echo "**** kABI checking is enabled in kernel SPEC file. ****"
    chmod 0755 $RPM_SOURCE_DIR/check-kabi
    if [ -e $RPM_SOURCE_DIR/Module.kabi_%{_target_cpu}$Flavour ]; then
        cp $RPM_SOURCE_DIR/Module.kabi_%{_target_cpu}$Flavour $RPM_BUILD_ROOT/Module.kabi
        $RPM_SOURCE_DIR/check-kabi -k $RPM_BUILD_ROOT/Module.kabi -s Module.symvers || exit 1
    else
        echo "**** NOTE: Cannot find reference Module.kabi file. ****"
    fi
%endif

Edítelo de forma que las 23 líneas originales queden cambiadas en las siguientes 24 líneas:

    # Create the kABI metadata for use in packaging
    echo "**** GENERATING kernel ABI metadata ****"
    gzip -c9 < Module.symvers > $RPM_BUILD_ROOT/boot/symvers-$KernelVer.gz
%if %{with_kabichk}
    chmod 0755 %_sourcedir/kabitool
    if [ ! -e $RPM_SOURCE_DIR/kabi_whitelist_%{_target_cpu}$Flavour ]; then
        echo "**** No KABI whitelist was available during build ****"
        %_sourcedir/kabitool -b $RPM_BUILD_ROOT/$DevelDir -k $KernelVer -l $RPM_BUILD_ROOT/kabi_whitelist
    else
        cp $RPM_SOURCE_DIR/kabi_whitelist_%{_target_cpu}$Flavour $RPM_BUILD_ROOT/kabi_whitelist
    fi
    rm -f %{_tmppath}/kernel-$KernelVer-kabideps
    %_sourcedir/kabitool -b . -d %{_tmppath}/kernel-$KernelVer-kabideps -k $KernelVer -w $RPM_BUILD_ROOT/kabi_whitelist

    echo "**** kABI checking is enabled in kernel SPEC file. ****"
    chmod 0755 $RPM_SOURCE_DIR/check-kabi
    if [ -e $RPM_SOURCE_DIR/Module.kabi_%{_target_cpu}$Flavour ]; then
        cp $RPM_SOURCE_DIR/Module.kabi_%{_target_cpu}$Flavour $RPM_BUILD_ROOT/Module.kabi
        $RPM_SOURCE_DIR/check-kabi -k $RPM_BUILD_ROOT/Module.kabi -s Module.symvers || exit 1
    else
        echo "**** NOTE: Cannot find reference Module.kabi file. ****"
    fi
%endif
    touch %{_tmppath}/kernel-$KernelVer-kabideps

Vaya a la línea 9136 donde verá un bloque de código que comienza con la frase # first copy everything:

    # first copy everything
    cp --parents `find  -type f -name "Makefile*" -o -name "Kconfig*"` $RPM_BUILD_ROOT/lib/modules/$KernelVer/build
    cp Module.symvers $RPM_BUILD_ROOT/lib/modules/$KernelVer/build
    cp Module.markers $RPM_BUILD_ROOT/lib/modules/$KernelVer/build
    mv $RPM_BUILD_ROOT/kabi_whitelist $RPM_BUILD_ROOT/lib/modules/$KernelVer/build
    if [ -e $RPM_BUILD_ROOT/Module.kabi ]; then
        mv $RPM_BUILD_ROOT/Module.kabi $RPM_BUILD_ROOT/lib/modules/$KernelVer/build
    fi
    cp symsets-$KernelVer.tar.gz $RPM_BUILD_ROOT/lib/modules/$KernelVer/build
    # then drop all but the needed Makefiles/Kconfig files

Edítelo de forma que las 10 líneas originales pasen a ser las siguientes 12 líneas:

    # first copy everything
    cp --parents `find  -type f -name "Makefile*" -o -name "Kconfig*"` $RPM_BUILD_ROOT/lib/modules/$KernelVer/build
    cp Module.symvers $RPM_BUILD_ROOT/lib/modules/$KernelVer/build
    cp Module.markers $RPM_BUILD_ROOT/lib/modules/$KernelVer/build
%if %{with_kabichk}
    mv $RPM_BUILD_ROOT/kabi_whitelist $RPM_BUILD_ROOT/lib/modules/$KernelVer/build
    if [ -e $RPM_BUILD_ROOT/Module.kabi ]; then
        mv $RPM_BUILD_ROOT/Module.kabi $RPM_BUILD_ROOT/lib/modules/$KernelVer/build
    fi
    cp symsets-$KernelVer.tar.gz $RPM_BUILD_ROOT/lib/modules/$KernelVer/build
%endif
    # then drop all but the needed Makefiles/Kconfig files

Finalmente, si tiene parches que aplicar, debe hacer referencia a ellos agregando dos líneas por cada parche. Luego de la línea 4432, que debe estar cerca del fin de las declaraciones de parches, agregue su declaración comenzando con el número 40000, de forma que su parche no quede en riesgo de conflicto con el espacio de parches del núcleo RHEL/CentOS. Por ejemplo:

Patch40000: my-custom-kernel.patch

Luego de la línea 8696 agregue la línea que aplica su parche. Todo lo que necesita hacer es agregar el número de parche que declaró anteriormente, y rpmbuild lo aplicará automáticamente para usted. Por ejemplo:

%patch40000 -p1

5. Compilando el nuevo núcleo

<!> En el paquete original hmaccalc existía un bug. Este ha sido corregido por la publicación de un paquete revisado en el repositorio FasTrack de TUV. Sin el paquete hmaccalc revisado, su compilación del núcleo fallará al principio de la fase de compilación de módulos. Como el Proyecto CentOS por el momento no provee un repositorio fasttrack con archivos para CentOS-5, hay dos formas de rodear este problema. O bien (1) obtener el paquete actualizado del repositorio ELRepo, o bien (2) usar la opción y argumento --without fips en la línea de comando de rpmbuild, detallada más abajo.

Comencemos la compilación:

[usuario@host SPECS]$ rpmbuild -bb --target=`uname -m` kernel-2.6.spec 2> build-err.log | tee build-out.log

Para los núcleos >= 2.6.18-53.el5, puede agregar algunas opciones útiles al comando rpmbuild usando los flags --with y/o --without, con sus argumentos asociados. Las opciones notables son:

--with baseonly
--with xenonly
--without up
--without xen
--without debug
--without debuginfo
--without fips
--without kabichk

Por ejemplo, para compilar solamente los paquetes base del núcleo use:

--with baseonly --without debug --without debuginfo

Para compilar sólo los paquetes del núcleo Xen use:

--with xenonly --without debug --without debuginfo

Para compilar sólo los paquetes del núcleo PAE use:

--without up --without xen --without debug --without debuginfo

Al completarse la compilación, los archivos rpm de su núcleo personalizado estarán en el directorio ~/rpmbuild/RPMS/`uname -m`/. Asegúrese de instalar estos archivos, como root, usando el comando rpm -ivh kernel-*.rpm . Nota: si ha compilado una versión del núcleo que es más antigua que una versión actualmente instalada, tendrá también que usar la opción --oldpackage con el comando rpm.

BAJO NINGUNA CIRCUNSTANCIA use el comando rpm -Uvh para instalar su núcleo porque esto actualizará (sobreescribirá) a la versión actualmente instalada. Por lo tanto, si tiene algún problema con su núcleo personalizado, no podrá volver a la versión anterior, funcional.

es/HowTos/Custom_Kernel (last edited 2019-12-09 09:11:35 by anonymous)