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)>>
- Está seguro? CentOS está diseñado para funcionar como un entorno completo. Si reemplazamos un componente crítico, puede que se vea afectado el funcionamiento del resto del sistema.
Está absolutamente seguro? Seriamente, el 99.9% de los usuarios ya no necesitan recompilar su propio núcleo. Quizás usted sólo necesite compilar un módulo del núcleo, en cuyo caso consulte Compilando módulos para el núcleo.
- La funcionalidad que usted necesita está disponible como un módulo separado del kernel actual?
La funcionalidad que usted necesita está disponible en el kernel plus localizado en el repositorio CentOSPlus?
- Última advertencia: si usted descompone el núcleo, o su computadora, tendrá que asumirlo, y adicionalmente, juntar usted los pedazos y guardarse las lamentaciones sobre por qué su sistema no arranca.
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:
yum groupinstall "Development Tools"# Esto asegurará que tenga todas las herramientas requeridas para la compilación.
yum install hmaccalc # Esto se requiere para proveer las herramientas capaces de calcular valores HMAC para los archivos.
yum install ncurses-devel # Esto se requiere para hacer que un comando make *config se ejecute correctamente.
yum install qt-devel # Esto solamente es necesario si desea usar make xconfig en lugar de make gconfig o make menuconfig.
El árbol completo de fuentes del núcleo. Siga las instrucciones en la Sección 2 de Necesito los fuentes del núcleo.
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.
|
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: |
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:
O bien el tipo apropiado de archivo de configuración, tomado del directorio ./configs/:
- Para CentOS-5: base, xen, o (si la arquitectura es de 32 bits) PAE
- Para CentOS-4: base, smp, xenU, o hugemem si la arquitectura es de 32 bits, largesmp si es de 64 bits.
- O bien el archivo de configuración del núcleo actualmente en ejecución, tomado del directorio /boot.
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.
|
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
|
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
|
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.