web-dev-qa-db-fra.com

"pas de version de symbole pour module_layout" lors d'une tentative de chargement de usbhid.ko

J'essaie de créer mon propre module pour usbhid.ko, mais une fois compilé, je ne peux pas le charger. dmesg indique no symbol version for module_layout. Je me demande quel est le problème? J'ai déjà utilisé le code source fourni par Ubuntu et je me suis également assuré que la version du noyau était la même.

26
SpecC

Plus précisément, le problème est que, lorsque vous avez construit votre module, le fichier Modules.symvers manquait probablement à l'arborescence des sources du noyau. Le système kbuild vous en avertit lorsque vous construisez votre module. Si Modules.symvers est manquant, vous verrez:

Avertissement: La version des symboles dump /usr/src/linux-2.6.34-12/Modules.symvers est manquante. les modules n'auront pas de dépendances ni de modversions.

Si votre noyau a CONFIG_MODVERSIONS activé, il sera exécuté pendant la phase de construction de votre pilote modpost scripts/mod/modpost avec l'option -m. Si vous êtes courageux et jetez un coup d'œil à la source scripts/mod/modpost.c, vous verrez que l'option -m ajoute le symbole _module_layout_ de vmlinux. Toutefois, si vous n'avez pas Modules.symvers de votre noyau, vous n'obtiendrez pas la valeur CRC de ce symbole et vous obtiendrez ce message d'erreur.

Il y a donc deux manières de contourner cela.

1) lancez une version complète de votre noyau en cours d’exécution pour générer Modules.symvers, puis reconstruisez votre module. [http://www.mjmwired.net/kernel/Documentation/kbuild/modules.txt][1]

51  === 2. How to Build External Modules
52  
53  To build external modules, you must have a prebuilt kernel available
54  that contains the configuration and header files used in the build.
55  Also, the kernel must have been built with modules enabled. If you are
56  using a distribution kernel, there will be a package for the kernel you
57  are running provided by your distribution.
58  
59  An alternative is to use the "make" target "modules_prepare." This will
60  make sure the kernel contains the information required. The target
61  exists solely as a simple way to prepare a kernel source tree for
62  building external modules.
63  
64  NOTE: "modules_prepare" will not build Module.symvers even if
65  CONFIG_MODVERSIONS is set; therefore, a full kernel build needs to be
66  executed to make module versioning work.

2) L’autre option est de dire à un modprobe stupide d’ignorer toute cette merde et de charger votre module de toute façon:

modprobe -f <module>

J'ai tendance à privilégier l'option 2 :)

21
Dan Gora

Installez les packages linux-headers et linux-source correspondant à votre noyau. Par exemple, pour le noyau 3.2.0-27-generic-pae, vous avez besoin des éléments suivants:

  1. linux-headers-3.2.0-27-generic-pae et
  2. linux-source-3.2.0-27-generic-pae.

Si la version des packages ci-dessus ne correspond pas à la version de votre noyau en cours d’exécution, vous devez remplacer $(uname -r) par la chaîne de version de votre package de noyau installé ci-dessus.
Pour l'exemple ci-dessus, la version du package est 3.2.0-27-generic-pae. Lorsque vous exécutez uname -r et que sa sortie est différente de 3.2.0-27-generic-pae, vous devez remplacer chaque $(uname -r) ci-dessous pour correspondre à la chaîne de version des packages installés.

  1. cd /usr/src/linux-source-$Version et décompressez l'archive .tar.bz2 à la place et cd dans le répertoire extrait - je suppose que vous l'avez déjà fait
  2. cp /boot/config-$(uname -r) .config dans le répertoire source du noyau
  3. cp /usr/src/linux-headers-$(uname -r)/Module.symvers . dans le répertoire source du noyau

Ensuite, dans le répertoire source du noyau, procédez comme suit:

  1. make prepare
  2. make scripts
  3. make M=drivers/usb/serial - change le chemin après M= pour répondre à vos besoins

Malheureusement, je ne sais pas comment construire un module spécifique tout en gardant Module.symvers intact. Faire make drivers/usb/serial/option.ko, par exemple, tue le fichier Module.symvers et vous vous retrouvez avec votre problème initial. L'utilisation du paramètre M= ne le détruit pas, mais vous devez construire tous les modules dans le chemin spécifié - et je n'ai pas encore trouvé le moyen de le contourner.

15
Radu C

Vous devez utiliser une configuration de noyau exactement identique avant d'exécuter make prepare. De même, si vous le construisez en dehors de l’arbre, vous devez le construire avec les en-têtes de noyau exactement identiques qui correspondent à votre noyau en cours d’exécution (ou à celui cible si vous ne l’utilisez pas au moment de la compilation).

1
Daniel T Chen