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.
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 :)
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:
linux-headers-3.2.0-27-generic-pae
etlinux-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.
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à faitcp /boot/config-$(uname -r) .config
dans le répertoire source du noyaucp /usr/src/linux-headers-$(uname -r)/Module.symvers .
dans le répertoire source du noyauEnsuite, dans le répertoire source du noyau, procédez comme suit:
make prepare
make scripts
make M=drivers/usb/serial
- change le chemin après M=
pour répondre à vos besoinsMalheureusement, 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.
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).