No se puede cargar el módulo: no está de acuerdo con la versión del símbolo module_layout

12

Siguiendo este tutorial para escribir mi primer controlador.

El Makefile es:

# Makefile – makefile of our first driver

# if KERNELRELEASE is defined, we've been invoked from the
# kernel build system and can use its language.
ifneq (${KERNELRELEASE},)
    obj-m := ofd.o
# Otherwise we were called directly from the command line.
# Invoke the kernel build system.
else
    KERNEL_SOURCE := /usr/src/linux 3.8
    PWD := $(shell pwd)
default:
    ${MAKE} -C ${KERNEL_SOURCE} SUBDIRS=${PWD} modules

clean:
    ${MAKE} -C ${KERNEL_SOURCE} SUBDIRS=${PWD} clean
endif

Y el código del controlador es:

* ofd.c – Our First Driver code */
#include <linux/module.h>
#include <linux/version.h>
#include <linux/kernel.h>

static int __init ofd_init(void) /* Constructor */
{
    printk(KERN_INFO "Namaskar: ofd registered");
    return 0;
}

static void __exit ofd_exit(void) /* Destructor */
{
    printk(KERN_INFO "Alvida: ofd unregistered");
}

module_init(ofd_init);
module_exit(ofd_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Anil Kumar Pugalia <email_at_sarika-pugs_dot_com>");
MODULE_DESCRIPTION("Our First Driver");

No hay error durante la realización. Pero cuando lo uso insmod ofd.kono puedo cargarlo. En dmesgeso dice:

no está de acuerdo con la versión del símbolo module_layout

  • uname -r devuelve '3.8.0-38-generic' y la fuente del núcleo también 3.8.
  • modprobe -f ofd.ko también falla

También:

#56~precise1-Ubuntu SMP Thu Mar 13 16:23:47 UTC 2014
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 12.04.4 LTS
Release:    12.04
Codename:   precise

¿Qué está pasando?

usuario2799508
fuente
Algunos comentarios obvios. Primero, ¿la fuente del núcleo es exactamente la misma que el núcleo de Ubuntu? Debería estar usando la fuente del núcleo de Ubuntu que corresponde exactamente a su núcleo. Upstream probablemente no funcionará, ya que las distribuciones parchan sus núcleos. En segundo lugar, si puedes compilar contra los encabezados del núcleo, no necesitas la fuente del núcleo. Los encabezados también deben estar disponibles como un paquete binario. También puede consultar el Manual del núcleo de Debian , que contiene información instructiva sobre los núcleos, etc. en Debian, que también se aplica a Ubuntu.
Faheem Mitha

Respuestas:

13

El kernel de Linux contiene estructuras de datos cuyo diseño varía no solo de una versión a otra, sino que también depende de las opciones de compilación. Como consecuencia, cuando compila un módulo del núcleo, necesita tener no solo los archivos de encabezado de la fuente del núcleo, sino también algunos archivos de encabezado que se generan durante la compilación del núcleo. Simplemente desempacar la fuente del núcleo no es suficiente.

Con los núcleos creados con CONFIG_MODVERSIONS, el número de versión puede diferir, pero el diseño de las estructuras de datos debe ser el mismo. Esta opción está activada en los núcleos de Ubuntu. Con esta opción, además de los encabezados, los módulos deben compilarse con el Module.symversarchivo adecuado . Ubuntu, como la mayoría de las distribuciones, incluye este archivo en el mismo paquete que los encabezados del núcleo resultantes de la compilación. El paquete de encabezado del kernel de Ubuntu se llama , por ejemplo .linux-headers-VERSION-VARIANTlinux-headers-3.8.0-38-generic

Con los núcleos construidos sin el CONFIG_MODVERSIONS(que puede ser el caso si compiló su propio núcleo), la comprobación al cargar un módulo es una comprobación de versión simple. Puede tomar la fuente de kernel desempaquetada, copiar la .configque se utilizó durante la compilación de su kernel en ejecución y ejecutar make modules_prepare. La responsabilidad recae sobre usted para verificar que cualquier parche que haya realizado en el núcleo no afecte la compatibilidad binaria.

Gilles 'SO- deja de ser malvado'
fuente