Nie można załadować modułu: Nie zgadza się z wersją symbolu moduł_wybuch

12

Po tym samouczku napisać mój pierwszy sterownik.

Plik Makefile to:

# 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

A kod sterownika to:

* 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");

Podczas make nie ma błędu. Ale kiedy korzystam, insmod ofd.konie mogę go załadować. W dmesgtym jest napisane:

nie zgadza się na temat wersji symbolu moduł_wyjściowy

  • uname -r zwraca „3.8.0-38-generic”, a źródło jądra również 3.8.
  • modprobe -f ofd.ko również zawodzi

Również:

#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

Co się dzieje?

użytkownik2799508
źródło
Kilka oczywistych komentarzy. Po pierwsze, czy źródło jądra jest dokładnie takie samo jak jądro Ubuntu? Powinieneś używać źródła jądra Ubuntu odpowiadającego dokładnie twojemu jądru. Upstream prawdopodobnie nie będzie działał, ponieważ dystrybucje łatają swoje jądra. Po drugie, po kompilacji z nagłówkami jądra, nie potrzebujesz źródła jądra. Nagłówki powinny być również dostępne jako pakiet binarny. Możesz także zajrzeć do Podręcznika jądra Debiana , który zawiera pouczające informacje o jądrach itp. Na temat Debiana, który dotyczy również Ubuntu.
Faheem Mitha

Odpowiedzi:

13

Jądro Linux zawiera struktury danych, których układ różni się nie tylko w zależności od wersji, ale także w zależności od opcji kompilacji. W związku z tym podczas kompilacji modułu jądra potrzebne są nie tylko pliki nagłówkowe ze źródła jądra, ale także niektóre pliki nagłówkowe generowane podczas kompilacji jądra. Samo rozpakowanie źródła jądra nie wystarczy.

W przypadku jądra zbudowanego za pomocą CONFIG_MODVERSIONSnumeru wersji może się różnić, ale układ struktur danych musi być taki sam. Ta opcja jest aktywowana w jądrach Ubuntu. Dzięki tej opcji, oprócz nagłówków, moduły muszą zostać skompilowane z odpowiednim Module.symversplikiem. Ubuntu, podobnie jak większość dystrybucji, zawiera ten plik w tym samym pakiecie, co nagłówki jądra wynikające z kompilacji. Pakiet nagłówka jądra Ubuntu nazywa się np .linux-headers-VERSION-VARIANTlinux-headers-3.8.0-38-generic

W jądrach zbudowanych bez CONFIG_MODVERSIONS(co może się zdarzyć, jeśli skompilowałeś własne jądro), sprawdzanie podczas ładowania modułu jest prostym sprawdzaniem wersji. Możesz pobrać rozpakowane źródło jądra, skopiować to, .configktóre było użyte podczas kompilacji uruchomionego jądra i uruchomić make modules_prepare. Na tobie spoczywa obowiązek sprawdzenia, czy jakakolwiek łatka wprowadzona do jądra nie wpływa na zgodność binarną.

Gilles „SO- przestań być zły”
źródło