[FrontPage] [TitleIndex] [WordIndex

This is a read-only archived version of wiki.centos.org

Compilando módulos para el núcleo

Created by AkemiYagi. Currently maintained by AlanBartlett and AkemiYagi.

Por favor tenga en cuenta que si hace cambios al núcleo, podrá ya no obtener soporte del equipo de desarrollo de CentOS. Los procedimientos que se describen aquí no están oficialmente aprobados por CentOS. Este tutorial se ofrece con la intención de que le sea útil cuando usted compile sus propios módulos.

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

En ocasiones, necesitamos modificar un módulo del núcleo o crear uno nuevo. Esto puede ser para agregar algunas características o para aplicar un parche. En este tutorial trataremos de aplicar una rectificación de un bug a un módulo existente y luego instalarlo.

Se supone que usted ya tiene instalado el árbol completo de los fuentes del núcleo. Si ha seguido la Sección 2 de Necesito los fuentes del núcleo, éste se encontrará en el directorio ~/rpmbuild/BUILD/kernel-2.6.18/linux-2.6.18.`uname -m`/. En este tutorial se asume un sistema con arquitectura de 32 bits. Por lo tanto la cadena devuelta por `uname -m` es 686, y así el directorio referenciado más arriba será ~/rpmbuild/BUILD/kernel-2.6.18/linux-2.6.18.i686/.

<!> Se recomienda fuertemente que la compilación de módulos no se realice como root (vea: Building Source RPM as non-root under CentOS).

1. Compilando un módulo del núcleo (*.ko)

Supongamos, como ejemplo, que estamos aplicando un parche al módulo cifs que está ubicado en el directorio ~/rpmbuild/BUILD/kernel-2.6.18/linux-2.6.18.i686/fs/cifs/.

1. Aplique los parches a los archivos fuente según sea necesario.

2. Cambie directorio a la raíz del árbol del núcleo. Si ésta es la primera vez que se compila el núcleo, configúrelo, recordando especificar, en el archivo de configuración (.conf) del componente relevante del núcleo, que se compile como módulo.

[user@host]$ cd ~/rpmbuild/BUILD/kernel-2.6.18/linux-2.6.18.i686
[user@host linux-2.6.18.i686]$ make oldconfig
[user@host linux-2.6.18.i686]$ make menuconfig
[user@host linux-2.6.18.i686]$ make prepare

3. Cree los archivos que se requieren para compilar módulos externos.

[user@host linux-2.6.18.i686]$ make modules_prepare

Nota: make modules_prepare no preparará un archivo Module.symvers, aunque se haya establecido el parámetro CONFIG_MODULEVERSIONING. Por lo tanto, para que el versionado de módulos funcione, se deberá haber ejecutado previamente una compilación del núcleo completo. Para más detalles ver Secciones #2.4 y #7 de /usr/share/doc/kernel-doc-2.6.18/Documentation/kbuild/modules.txt

4. Compile el módulo especificando el camino relativo al Makefile y código fuente del módulo.

[user@host linux-2.6.18.i686]$ make M=fs/cifs

Nota: El directorio conteniendo el módulo puede estar ubicado en cualquier lugar. Si, por ejemplo, está en ~/mycifs/ , corra el siguiente comando asegurándose de estar aún en la raíz del árbol de fuentes del núcleo.

[user@host linux-2.6.18.i686]$ make M=~/mycifs

5. A menos que haya compilado este módulo con propósitos de depuración, ahora deben quitarse los símbolos innecesarios.

[user@host linux-2.6.18.i686]$ strip --strip-debug fs/cifs/cifs.ko

6. En este ejemplo, acaba de ser creado el archivo cifs.ko. Como root, copie el archivo .ko al directorio /lib/modules/<kernel-version>/extra/.

[root@host linux-2.6.18.i686]# cp fs/cifs/cifs.ko /lib/modules/`uname -r`/extra

Para mayores detalles de los directorios donde deben instalarse los módulos, vea la Sección #6 de /usr/share/doc/kernel-doc-2.6.18/Documentation/kbuild/modules.txt

7. Como root, corra el comando depmod para actualizar los archivos de dependencias del módulo.

[root@host linux-2.6.18.i686]# depmod -a

8. Se requieren algunos pasos más para compilar los diferentes módulos para los diferentes tipos de núcleo. Edite el Makefile principal en el directorio raíz del árbol de fuentes del núcleo. Para CentOS 5, busque:

EXTRAVERSION = -prep

y reemplácelo, según corresponda, con:

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

El número no es muy importante si vamos a usar modprobe para instalar el módulo. Un módulo -164.el5 se instalará en un núcleo -164.15.1.el5, etc. Sin embargo, los modificadores PAE y xen deben usarse obligatoriamente para esos tipos de núcleos.

Sugerencia: Luego de compilar el módulo para el núcleo estándar, edite la línea EXTRAVERSION agregando PAE o xen y corra make modules_prepare. Luego corra make M=xxx para compilar el módulo para la versión del núcleo especificada en la línea EXTRAVERSION.

2. Compilando un módulo del núcleo usando Dynamic Kernel Module Support (DKMS)

El método descrito arriba compila un módulo para una versión particular del núcleo. Si actualizamos el núcleo o cambiamos la arquitectura de hardware, tendremos que reconstruir manualmente el módulo nuevamente. DKMS (soporte dinámico de módulos del núcleo) es básicamente un árbol duplicado, fuera de los fuentes del núcleo, que contiene los fuentes y binarios compilados para un módulo específico. DKMS puede ser invocado para compilar, instalar o desinstalar módulos. DKMS requiere que los fuentes del módulo estén localizados en su sistema. El binario de DKMS se encarga de compilar e instalar los módulos en aquellos núcleos que podamos tener en nuestro sistema.

Aquí usaremos el mismo ejemplo que antes y compilaremos e instalaremos el módulo cifs. Necesitaremos contar con poderes de root durante toda esta sección.

1. Instale el paquete kernel-devel que coincida con su núcleo actual.

2. Instale el paquete dkms del repositorio Repositories/RPMForge.

3. Cree un directorio /usr/src/<module>-<module-version>/

[root@host]# mkdir /usr/src/cifs-1.45fixed/

4. Copie los fuentes del módulo a ese directorio.

[root@host]# cd ~/rpmbuild/BUILD/kernel-2.6.18/linux-2.6.18-i686/fs/cifs
[root@host cifs]# cp -a * /usr/src/cifs-1.45fixed/

5. Cree un archivo dkms.conf en el directorio /usr/src/<module>-<module-version>/

[root@host cifs]# cd /usr/src/cifs-1.45fixed
[root@host cifs-1.45fixed]# vi dkms.conf

El archivo dkms.conf deberá contener estas líneas:

PACKAGE_NAME="cifs"
PACKAGE_VERSION="1.45fixed"
BUILT_MODULE_NAME[0]="cifs"
DEST_MODULE_LOCATION[0]="/kernel/fs/cifs/"
AUTOINSTALL="yes"

Nota: La línea DEST_MODULE_LOCATION[0] será ignorada durante la instalación del módulo porque ésta siempre se efectuará al directorio /lib/modules/<kernel-version>/extra/. Este parámetro, sin embargo, será usado al desinstalar un módulo. Equivaldrá a la ubicación donde será repuesto, en caso de que lo hubiera, un módulo anterior previamente almacenado.

6. Agregue el <module>/<module-version> al árbol DKMS.

[root@host cifs-1.45fixed]# dkms add -m cifs -v 1.45fixed

7. Compile el módulo bajo control de DKMS.

[root@host cifs-1.45fixed]# dkms build -m cifs -v 1.45fixed

8. Instale el módulo, nuevamente bajo control de DKMS.

[root@host cifs-1.45fixed]# dkms install -m cifs -v 1.45fixed

Otras acciones notables de DKMS son uninstall, remove, status y mkrpm que desinstala el módulo del núcleo, quita el <module>/<module-version> del árbol DKMS, muestra el estado actual de DKMS del sistema y crea un archivo rpm en el directorio /var/lib/dkms/<module>/<module-version>/rpm/ respectivamente.

Véase también:

3. Creando un paquete rpm de un módulo del núcleo (kmod)

También se pueden crear archivos rpm para módulos del núcleo. El paquete rpm de un módulo del núcleo (kmod) puede ser instalado usando el comando rpm como con cualquier otro paquete. Sin embargo, el empaquetado rpm de módulos del núcleo se maneja en forma diferente del proceso de empaquetado estándar. El ejemplo más abajo provee la técnica básica de empaquetado de rpm para módulos del núcleo.

Nuevamente usaremos el módulo cifs como ejemplo y crearemos un conjunto de archivos rpm kmod-cifs.

1. Instale todos los paquetes kernel-devel para su núcleo actual.

2. El código fuente parchado está en el directorio ~/rpmbuild/BUILD/kernel-2.6.18/linux-2.6.18.i686/fs/cifs/ como en la Sección 1, más arriba. Cree una copia de trabajo de ese directorio.

[user@host]$ mkdir ~/cifs-1.45/
[user@host]$ cd ~/rpmbuild/BUILD/kernel-2.6.18/linux-2.6.18.i686/fs/cifs
[user@host]$ cp -a * ~/cifs-1.45/

3. Cree un archivo tarball comprimido con bzip2 conteniendo el directorio de los fuentes.

[user@host]$ cd
[user@host]$ tar -jcf cifs-1.45.tar.bz2 cifs-1.45/

4. Copie el tarball comprimido al directorio SOURCES.

[user@host]$ cp cifs-1.45.tar.bz2 ~/rpmbuild/SOURCES/

5. Haga una copia del script kmodtool (parte del paquete redhat-rpm-config) en el directorio SOURCES.

[user@host]$ cd ~/rpmbuild/SOURCES/
[user@host SOURCES]$ cp /usr/lib/rpm/redhat/kmodtool kmodtool-cifs

6. Edite su copia del archivo kmodtool-cifsasegurándose de que la línea que referencia a kmod-common esté comentada, y agregando una línea que al expandirse se convierta en una referencia a un archivo cifs.conf bajo la sección %files.

[user@host SOURCES]$ vi kmodtool-cifs

Línea 105 en adelante --

#
# RHEL5 - Remove common package requirement on general kmod packages.
# Requires: ${kmod_name}-kmod-common >= %{?epoch:%{epoch}:}%{version}
#

Línea 168 en adelante --

echo "%files         -n kmod-${kmod_name}${dashvariant}"

if [ "" == "$kmp_override_filelist" ];
then
    echo "%defattr(644,root,root,755)"
    echo "/lib/modules/${verrel}${variant}/"
    echo "%config /etc/depmod.d/${kmod_name}.conf"
    #BZ252188 - I've commented this out for the moment since RHEL5 doesn't
    #           really support external firmware e.g. at install time. If
    #           you really want it, use an override filelist solution.
    #echo "/lib/firmware/"
else
    cat "$kmp_override_filelist"
fi

7. Cree un archivo cifs-kmod.spec en el directorio SPECS.

[user@host SOURCES]$ cd ~/rpmbuild/SPECS/
[user@host SPECS]$ vi cifs-kmod.spec

# Define the kmod package name here.
%define  kmod_name cifs
#
Name:    %{kmod_name}-kmod
Version: 1.45
Release: 1.el5
Group:   System Environment/Kernel
License: GPL v2
Summary: CentOS-5 bug-fixed cifs module
URL:     http://www.centos.org/
#
BuildRoot:     %{_tmppath}/%{name}-%{version}-%{release}-build-%(%{__id_u} -n)
ExclusiveArch: i686 x86_64
#
# Sources.
Source0:  %{kmod_name}-%{version}.tar.bz2
Source10: kmodtool-%{kmod_name}
#
# If kversion isn't defined on the rpmbuild line, build for the current kernel.
%{!?kversion: %define kversion %(uname -r)}
#
# Define the variants for each architecture.
%define basevar ""
%ifarch i686
%define paevar PAE
%endif
%ifarch i686 x86_64
%define xenvar xen
%endif
#
# If kvariants isn't defined on the rpmbuild line, build all variants for this architecture.
%{!?kvariants: %define kvariants %{?basevar} %{?xenvar} %{?paevar}}
#
# Magic hidden here.
%define kmodtool sh %{SOURCE10}
%{expand:%(%{kmodtool} rpmtemplate_kmp %{kmod_name} %{kversion} %{kvariants} 2>/dev/null)}
#
%description
This package provides the CentOS-5 bug-fixed cifs kernel module (bug #1776).
It is built to depend upon the specific ABI provided by a range of releases
of the same variant of the CentOS kernel and not on any one specific build.
#
%prep
%setup -q -c -T -a 0
for kvariant in %{kvariants} ; do
    %{__cp} -a %{kmod_name}-%{version} _kmod_build_$kvariant
    %{__cat} <<-EOF >_kmod_build_$kvariant/%{kmod_name}.conf
        override %{kmod_name} * weak-updates/%{kmod_name}
        EOF
done
#
%build
for kvariant in %{kvariants} ; do
    ksrc=%{_usrsrc}/kernels/%{kversion}${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/%{kversion}${kvariant:+-$kvariant}-%{_target_cpu}
    pushd _kmod_build_$kvariant
    %{__make} -C "${ksrc}" modules_install M=$PWD
    %{__install} -d ${INSTALL_MOD_PATH}/etc/depmod.d/
    %{__install} %{kmod_name}.conf ${INSTALL_MOD_PATH}/etc/depmod.d/
    popd
done
# Strip the module(s).
find ${INSTALL_MOD_PATH} -type f -name \*.ko -exec strip --strip-debug \{\} \;
#
%clean
%{__rm} -rf $RPM_BUILD_ROOT
#
%changelog
* Mon Aug 17 2009 Alan Bartlett <ajb@elrepo.org>
- Revised the kmodtool file and this spec file.
#
* Thu May 14 2009 Alan Bartlett <ajb@elrepo.org>
- Refined this spec file.
#
* Fri Mar 20 2009 Alan Bartlett <ajb@elrepo.org>
- Added a line to strip the modules.
#
* Thu Dec 25 2008 Alan Bartlett <ajb@elrepo.org>
- Re-aligned this spec file to RHEL standards.
#
* Sat Dec 13 2008 Alan Bartlett <ajb@elrepo.org>
- Added a .el5 identifier to the release.
#
* Tue Jul 29 2008 Alan Bartlett <ajb@elrepo.org>
- Revised this specification file.
#
* Fri May 18 2007 Akemi Yagi <toracat@centos.org>
- Initial example kmod specification file.

8. Construya el paquete.

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

Si no desea construir los paquetes kmod para el núcleo que actualmente está ejecutando, puede especificar la versión en la línea de comandos. Por ejemplo:

[user@host SPECS]$ rpmbuild -bb --target=`uname -m` --define 'kversion 2.6.18-164.el5' cifs-kmod.spec 2> build-err.log | tee build-out.log

construirá los paquetes kmod para el núcleo 2.6.18-164.el5.

De manera similar, puede seleccionar para qué variante del núcleo construirá los paquetes kmod. Por ejemplo:

[user@host SPECS]$ rpmbuild -bb --target=`uname -m` --define 'kvariants ""' cifs-kmod.spec 2> build-err.log | tee build-out.log

construirá únicamente el paquete kmod base-kernel.

Al completarse la construcción, quedará un conjunto de archivos rpm kmod-cifs en el directorio ~/rpmbuild/RPMS/`uname -m`/.

Vea también:


2023-09-11 07:23