void alpha_function(void) { printk(KERN_INFO "alpha_function: exécution\r\n"); }
static int __init alpha_init(void) { printk(KERN_INFO "moduleAlpha: initialisation\r\n"); return 0; }
static void __exit alpha_exit(void) { printk(KERN_INFO "moduleAlpha: nettoyage\r\n"); }
EXPORT_SYMBOL_GPL(alpha_function);
MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("Module Alpha - fonctions utilitaires"); MODULE_AUTHOR("Auteur");
module_init(alpha_init); module_exit(alpha_exit);
Makefile associé : ```
obj-m += moduleAlpha.o
KVERS = $(shell uname -r)
OUTPUT_DIR := $(shell pwd)
build: kernel_modules
kernel_modules:
make -C /lib/modules/$(KVERS)/build M=$(OUTPUT_DIR) modules
clean:
make -C /lib/modules/$(KVERS)/build M=$(OUTPUT_DIR) clean
Après compilation, le fichier Module.symvers contient le symbole exporté : ```
$ make
$ cat Module.symvers
0xcaecb33a alpha_function /path/to/moduleAlpha/moduleAlpha EXPORT_SYMBOL_GPL
Le symbole `alpha_function` est maintenant visible dans la table d'exportation. ### ModuleB - Importation de symboles Le second module declare externe la fonction à utiliser, puis l'appelle normalement comme une fonction locale. Code source de moduleBeta.c : ```
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
extern void alpha_function(void);
static int __init beta_init(void)
{
printk(KERN_INFO "moduleBeta: initialisation\r\n");
alpha_function();
return 0;
}
static void __exit beta_exit(void)
{
printk(KERN_INFO "moduleBeta: nettoyage\r\n");
}
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Module Beta - appel de fonctions externes");
MODULE_AUTHOR("Auteur");
module_init(beta_init);
module_exit(beta_exit);
Makefile modifié pour inclure la table de symboles : ``` obj-m += moduleBeta.o
KVERS = $(shell uname -r) OUTPUT_DIR := $(shell pwd)
Import de la table des symboles du module Alpha
KBUILD_EXTRA_SYMBOLS += /path/to/moduleAlpha/Module.symvers
build: kernel_modules
kernel_modules: make -C /lib/modules/$(KVERS)/build M=$(OUTPUT_DIR) modules
clean: make -C /lib/modules/$(KVERS)/build M=$(OUTPUT_DIR) clean
Procédure de test -- 1. Chargement du module Alpha : ```
$ sudo insmod moduleAlpha.ko
$ dmesg | tail
[ 1567.642823] moduleAlpha: initialisation!
$ grep alpha_function /proc/kallsyms
ffffffffc071b030 r __ksymtab_alpha_function [moduleAlpha]
ffffffffc071a000 t alpha_function [moduleAlpha]
- Chargement du module Beta : ``` $ sudo insmod moduleBeta.ko $ dmesg | tail [ 1900.514577] moduleBeta: initialisation [ 1900.514580] alpha_function: exécution
Le module Beta appelle avec succès la fonction `alpha_function` du module Alpha. Erreurs courantes -- 1. **Compilation de Beta avant Alpha** : Le symbole n'existe pas encore ```
WARNING: "alpha_function" [/path/to/moduleBeta/moduleBeta.ko] undefined!
- Absence de KBUILD_EXTRA_SYMBOLS : Le linker ne peut pas résoudre la référence ``` WARNING: "alpha_function" [/path/to/moduleBeta/moduleBeta.ko] undefined!
3. **Chemin relatif au lieu de absolu** :KBUILD_EXTRA_SYMBOLS requiert un chemin absolu vers le fichier Module.symvers Ordre de chargement et déchargement -- Pour un fonctionnement correct : - **Chargement** : charger d'abord le module Alpha, puis le module Beta - **Déchargement** : décharger d'abord le module Beta, puis le module Alpha Tentative de déchargement dans le mauvais ordre : ```
$ sudo rmmod moduleAlpha
rmmod: ERROR: Module moduleAlpha is in use by: moduleBeta