Construyendo módulos para el núcleo

En ocasiones usted necesita modificar un módulo del núcleo o crear uno nuevo. Esto puede adicionar algunas características o simplemente aplicar un parche. En este ejemplo, trataremos de aplicar una rectificación de error a un módulo existente y luego recompilarlo.

Importante

Si usted realiza cambios a su núcleo, usted no obtendrá mantenimiento o ayuda del equipo de CentOS. El procedimiento descrito en esta página no está oficialmente probado por CentOS. Este documento es publicado con la esperanza de ser útil cuando construya sus propios módulos para el núcleo.

Asumimos que ya tenga un árbol con el código fuente del núcleo. Si usted siguió Necesito el código fuente del núcleo, el árbol con el código fuente está en /usr/src/redhat/BUILD/kernel-<version>/linux-<version>. Si usted siguió Necesito construir un núcleo personalizado, el árbol con el código fuente está en ~/rpmbuild/BUILD/kernel-<version>/linux-<version>.

Está contraindicado realizar la construcción de módulos como root. Para correr el proceso como un usuario diferente a root, haga lo siguiente:

cd
mkdir -p rpmbuild/{SRPMS,RPMS,SPECS,BUILD,SOURCES}
echo "%_topdir %(echo $HOME)/rpmbuild" > .rpmmacros

Esto creará el árbol de directorio en ~/rpmbuild y el código fuente del núcleo estará en ~/rpmbuild/BUILD/kernel-<version>/linux-<version>.

Vea además: Artículo de Construcción de RPMs en CentOS con usuarios diferentes a root: http://www.owlriver.com/tips/

1. Construyendo un módulo *.ko para el núcleo

Vamos a asumir que nuestro código fuente para el núcleo esta en ~/rpmbuild/BUILD/kernel-2.6.18/linux-2.6.18.i686 y vamos a arreglar el módulo cifs que está en ~/rpmbuild/BUILD/kernel-2.6.18/linux-2.6.18.i686/fs/cifs.

  1. Aplicar parches a los ficheros fuentes que lo requieran.
  2. Cambiar al directorio root del código fuente del núcleo y si esta es la primera vez que el núcleo es compilado, configure el núcleo.
    •   cd ~/rpmbuild/BUILD/kernel-2.6.18/linux-2.6.18.i686
        make oldconfig
        make prepare
  3. Crear los ficheros requeridos por la compilación externa de módulos.
    •   make modules_prepare

      Nota

      modules_prepare no construirán Module.symvers aun si CONFIG_MODULEERSIONING está fijada. Sin embargo una construcción completa del núcleo necesita ser ejecutada para crear versiones de módulos que trabajen. Para los detalles, vea: /usr/share/doc/<kernel_version>/Documentation/kbuild/modules.txt .

  4. Compilar el módulo especificando el camino relativo al Makefile y al código fuente del módulo.
    •   make M=fs/cifs

      Nota

      el directorio completo que contiene el módulo puede ser ubicado en cualquier parte. Si este está en ~mycifs, ejecute el comando siguiente asegurándose que se encuentre en el directorio raiz del código fuente del núcleo.

        make M=~/mycifs
  5. En nuestro ejemplo, hemos creado cifs.ko en el directorio fuente del módulo. Si usted compiló el módulo fuera de el árbol fuente, copie el fichero .ko a /lib/modules/[version]/updates y ejecute el comando: (donde [version] es la cadena referente a la versión del núcleo)

    • depmod -v [version]

      Usando el directorio updates actualizará los módulos del núcleo estándar y será fácil moverlos a nuevos núcleos más tarde según convenga.

Para hacer esto un par de pasos más largo, es necesario obtener diferentes módulos para diferentes tipos de núcleos.

En uno necesitamos editar el Makefile en el directorio principal del fuente del núcleo ... para el caso de CentOS 5 usted puede abrir el Makefile y buscar:

EXTRAVERSION = -prep

y reemplazarla con (a conveniencia):

EXTRAVERSION = -8.1.1.el5
EXTRAVERSION = -8.1.1.el5PAE
EXTRAVERSION = -8.1.1.el5xen
EXTRAVERSION = -8.1.1.el5.centos.plus
EXTRAVERSION = -8.1.1.el5.centos.plusPAE
EXTRAVERSION = -8.1.1.el5.centos.plusxen

El número no es muy importante si usted va a realizar un modprobe del módulo .ko ( un -8.el5 instalará un núcleo -8.1.1.el5). Sin embargo los modificadores PAE y xen son requeridos para usar esos tipos de núcleos.

Truco

Después de compilar uno de los núcleos estándar, edite la línea EXTRAVERSION para adicionar PAE o xen y ejecute make modules_prepare. Luego ejecute make M=xxx para compilar el módulo de la versión especificada en la línea EXTRAVERSION.

2. Construir un módulo para el núcleo usando Mantención Dinámica para los Módulos del Núcleo

El método descrito arriba construye un módulo para una versión específica del núcleo. Si usted mejora el núcleo o cambia de arquitectura, usted tendrá que reconstruir el módulo manualmente otra vez. El marco de trabajo para la mantención dinámica de módulos para el núcleo (DKMS) es básicamente un árbol duplicado fuera del árbol del núcleo que mantiene el fuente del módulo y los binarios de los módulos compilados. DKMS crea un ejecutable que puede ser llamado para construir, instalar o desinstalar módulos. DKMS necesita tener localizado el código fuente del módulo solo en el sistema del usuario. El ejecutable DKMS se encarga de construir e instalar el módulo para cualquier núcleo que los usuarios puedan tener en sus sistemas.

Aquí, usaremos el mismo ejemplo de arriba y construye el módulo cifs y crea su fichero rpm.

Instale el paquete dkms desde RPMForge.

Cree un directorio mkdir /usr/src/<module>-<module-version>/. En nuestro ejemplo este debe verse de la siguiente forma:

mkdir /usr/src/cifs-1.45fixed/

En este directorio, necesita tener:

El fichero dkms.conf tiene las líneas siguientes:

PACKAGE_NAME=cifs
PACKAGE_VERSION=1.45fixed
BUILT_MODULE_NAME[0]=cifs
AUTOINSTALL="YES"

Nota

Las líneas DEST_MODULE_LOCATION, si existen, serán ignoradas porque el destino siempre es /extra en CentOS 5.

Ejecute dkms <command> -m <module> -v <module-version> en este orden:

dkms add -m cifs -v 1.45fixed
dkms build -m cifs -v 1.45fixed
dkms mkrpm -m cifs -v 1.45fixed

El fichero rpm será creado en la ubicación /usr/src/redhat/RPMS/noarch.

/usr/src/redhat/RPMS/noarch/cifs-1.45fixed-1dkms.noarch.rpm

Vea además:

3. Construyendo el paquete de un módulo para el núcleo (kmod)

(Borrador)

Usted puede producir ficheros rpm para los módulos de su núcleo. El paquete del módulo para el núcleo (kmod) será cargado usando el comando rpm como para los otro paquetes. Sin embargo, el empaquetado rpm de módulos para el núcleo es manipulado de forma diferente al proceso estándar de empaquetado. El ejemplo siguiente muestra algunas técnicas básicas de empaquetado que pueden servirle de punto de partida.

Aquí continuaremos con la construcción del módulo cifs y trataremos de crear un rpm kmod-cifs.

Lo primero que necesitamos es el tarball que contiene el fuente del módulo. Suponiendo que el árbol de construcción está en /usr/src/redhat/ y los ficheros fuentes están en /usr/src/cifs-1.45fixed/ como en la sección de arriba.

cd /usr/src/cifs-1.45fixed
cp Makefile Kbuild
cd ..
tar cifs-1.45fixed.tar cifs-1.45fixed/
bzip2 cifs-1.45fixed.tar

Esto escribe un fichero con el nombre cifs-1.45fixed.tar.bz2. Fíjense que usted necesita incluir el nombre del directorio. Copie este fichero a /usr/src/redhat/SOURCES/.

Lo siguiente que necesitamos es un script llamado kmodtool. Este forma parte del paquete redhat-rpm-config. Copie el script a el directorio SOURCE.

cp /usr/lib/rpm/redhat/kmodtool /usr/src/redhat/SOURCES/

Edite el fichero kmodtool y comente las líneas que contengan kmod-common

# Requires:         ${kmod_name}-kmod-common >= %{?epoch:%{epoch}:}%{version}

Ahora necesitamos crear un fichero .spec. Aquí esta un fichero de ejemplo para el módulo cfis que estamos construyendo.

%define   kmodtool sh ../SOURCES/kmodtool

# hardcode for now:
%{!?kversion: %{expand: %%define kversion %(uname -r)}}

%define kmod_name cifs
%define kverrel %(%{kmodtool} verrel %{?kversion} 2>/dev/null)

%define upvar ""
%ifarch i686
%define paevar PAE
%endif
%ifarch i686 x86_64
%define xenvar xen
%endif

%{!?kvariants: %define kvariants %{?upvar} %{?xenvar} %{paevar} %{?kdumpvar}}

Name:       %{kmod_name}-kmod
Version:    1.45
Release:    1.1.2.6.18_8.1.3.el5.centos
Summary:    cifs 1.45 CentOS5 kmod (bug fix)

License:    Distributable
Group:      System Environment/Kernel
URL:        http://www.centos.org/

#Source is created from these files:
Source0:        cifs-1.45-el5.centos.tar.bz2
BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
ExclusiveArch:  i686 x86_64

%description
This package provides a cifs kernel module with a bug fix (centos bug# 1776).  It is
built to depend upon the specific ABI provided by a range of releases of the
same variant of the RHEL kernel and not on any one specific build.

# magic hidden here:
%define kmp_version %{version}
%define kmp_release %{release}
{expand:%(%{kmodtool} rpmtemplate_kmp %{kmod_name} %{kverrel} %{kvariants} 2>/dev/null)}

%prep
%setup -q -c -T -a 0
for kvariant in %{kvariants} ; do
    cp -a cifs-1.45 _kmod_build_$kvariant
done


%build
for kvariant in %{kvariants}
do
    ksrc=%{_usrsrc}/kernels/%{kverrel}${kvariant:+-$kvariant}-%{_target_cpu}
    pushd _kmod_build_$kvariant
    make -C "${ksrc}" modules M=$PWD
    popd
done

%install
export INSTALL_MOD_PATH=$RPM_BUILD_ROOT
export INSTALL_MOD_DIR=extra/%{kmod_name}
for kvariant in %{kvariants}
do
    ksrc=%{_usrsrc}/kernels/%{kverrel}${kvariant:+-$kvariant}-%{_target_cpu}
    pushd _kmod_build_$kvariant
    make -C "${ksrc}" modules_install M=$PWD
    popd
done

%clean
rm -rf $RPM_BUILD_ROOT

%changelog
* Fri May 18 2007 Akemi Yagi <amyagi@gmail.com>
- Example file. 1.45-1.1.2.6.18_8.1.3.el5.centos

Nombre este fichero cfis.45fixed.spec y ubíquelo en /usr/src/redhat/SPECS.

Ahora estamos listos para construir el paquete

rpmbuild -ba --target `uname -m` cifs1.45fixed.spec

Si todo va bien, usted encontrará los ficheros kmod-cifs-xxx.rpm en /usr/src/redhat/RPMS/`uname -m`.

Vea además:

es/HowTos/BuildingKernelModules (last edited 2008-03-04 06:19:25 by AlainRegueraDelgado)