Appel de fonctions entre modules kernel Linux (KO)

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]

  1. 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!

  1. 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

Étiquettes: linux-kernel ko-modules export-symbol gpl kbuild

Publié le 13 juillet à 04h34