«Pas de version de symbole pour module_layout» lors de la tentative de chargement de usbhid.ko

27

J'essaye de construire mon propre module pour usbhid.ko, mais après avoir compilé, je ne peux pas charger le module. dmesgdit no symbol version for module_layout. Je me demande quel est le problème? J'ai déjà utilisé la source du noyau fournie par Ubuntu et je me suis également assuré que la version du noyau est la même.

SpecC
la source

Réponses:

22

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

Avertissement: le vidage de la version du symbole /usr/src/linux-2.6.34-12/Modules.symvers est manquant; les modules n'auront ni dépendances ni modifications.

Si votre noyau est CONFIG_MODVERSIONSactivé, alors pendant la phase modpost de construction de votre pilote, il exécutera scripts / mod / modpost avec l'option -m. Si vous êtes courageux et jetez un oeil à la source scripts / mod / modpost.c , vous verrez que l'option -m ajoute le symbole _module_layout_ de vmlinux, cependant si vous n'avez pas Modules.symvers de votre noyau, vous n'obtiendrez pas la valeur CRC pour ce symbole et vous vous retrouverez avec ce message d'erreur.

Il y a donc deux façons de contourner cela.

1) exécutez 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 3/10]

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 à stupide modprobe d'ignorer toutes ces conneries et de charger votre module de toute façon:

modprobe -f <module>

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

Dan Gora
la source
1
+1 pour "dites à stupide modprobe d'ignorer toutes ces conneries et de charger quand même votre module".
Hayri Uğur Koltuk
J'ai essayé 2 et j'ai constaté que le module ne se chargera pas automatiquement au démarrage. existe-t-il un moyen de -f au démarrage?
Justin Zhang
17

Faites installer à la fois les packages linux-headerset linux-sourcecorrespondant à votre noyau. Par exemple, pour le noyau, 3.2.0-27-generic-paevous avez besoin de:

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

Dans le cas où la version des packages ci-dessus ne correspond pas à votre version de 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 -ret que sa sortie est différente, 3.2.0-27-generic-paevous devez remplacer chacun $(uname -r)ci-dessous pour faire correspondre la chaîne de version des packages installés.

  1. cd /usr/src/linux-source-$Version et décompressez l'archive .tar.bz2 en 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

Après cela, dans le répertoire source du noyau, procédez comme suit:

  1. make prepare
  2. make scripts
  3. make M=drivers/usb/serial- changez le chemin après M=pour l'adapter à vos besoins

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

Radu C
la source
Cela semble être la meilleure façon de faire les choses, au cas où vous compileriez le module dans la même version arborescente ...
Treviño
2

Vous devez utiliser la configuration du noyau exactement identique avant de lancer make prepare. De plus, si vous le construisez à partir de l'arborescence, vous devez le construire par rapport aux en-têtes de noyau exactement identiques correspondant à votre noyau en cours d'exécution (ou à celui cible si vous ne l'exécutez pas au moment de la compilation).

Daniel T Chen
la source
"make mrproper", "cp / boot / config - $ (uname -r) .config", "make oldconfig", "make prepare", "make scripts" J'ai utilisé ces instructions pour préparer la compilation. Je voudrais savoir si j'ai copié le bon fichier de configuration? semble qu'il n'y ait qu'une seule configuration qui correspond à ma version du noyau dans / boot /. désolé pour le formatage car la boîte de commentaire n'a pas de format ....
SpecC
Oui, cela semble correct. Où invoquez-vous la construction, et si ce n'est pas du répertoire toplevel, quelle valeur SUBDIRS passez-vous?
Daniel T Chen
Merci pour la réponse. quand j'ai essayé de construire usbhid.ko. J'ai utilisé cette commande "make modules SUBDIRS = drivers / hid / usbhid"
SpecC
lorsque j'ai exécuté la commande "make modules SUBDIRS = drivers / hid / usbhid", j'obtiens l'avertissement suivant "AVERTISSEMENT: le symbole de version de vidage /usr/src/linux-source-2.6.31/Module.symvers est manquant; les modules auront pas de dépendances et de modversions. "
SpecC
@SpecC Lorsque vous étudiez votre problème, mettez à jour votre question d'origine en suivant les étapes que vous suivez. Ensuite, Dan mettra à jour sa réponse, et vous continuerez à mettre à jour jusqu'à ce que vous le trouviez au lieu d'une chaîne de commentaires qui finit par être enterrée, consultez le guide pour plus de conseils: meta.askubuntu.com/questions/257/how-does-ask -ubuntu-work
Jorge Castro