Ajouter un module noyau personnel dans Buildroot

Publié par cpb
Juil 22 2014

Module kernel dans BuildrootIl m’arrive fréquemment de développer de petits drivers Linux pour des clients afin de gérer des périphériques spécifiques. Ceci la plupart du temps dans un contexte de système embarqué.

Pour la construction d’un système Linux embarqué, ma préférence va généralement à l’environnement de production Buildroot. Celui-ci est plus léger (mais moins riche, il est vrai) que son principal concurrent Yocto.

La documentation de Buildroot est claire et bien fournie, toutefois il n’est pas très facile d’y trouver comment intégrer un driver Linux spécifique, développé pour une cible donnée. Voici donc un petit rappel des fichiers à ajouter ou modifier.

Module spécifique

Je prendrai comme exemple ici un petit module de démonstration que j’ai développé pour lire la position d’un capteur incrémental d’angle de rotation. Ce code est encore en cours de mise au point,  j’en parlerai plus en détail dans un prochain article. Nous allons l’employer simplement à titre d’exemple d’un module kernel fourni sous forme de fichier source avec un Makefile classique.

Le driver est stocké sur Github à l’adresse suivante  git://github.com/cpb-/rotation-sensor-module.git

Buildroot

J’utilise la dernière version de Buildroot (2014-05) que je décompresse. Puis je me place dans son répertoire principal.

[~]$ tar xjf buildroot-2014.05.tar.bz2
[~]$ cd buildroot-2014.05/
arch/   CHANGES           configs/  fs/       Makefile.legacy  support/
board/  Config.in         COPYING   linux/    package/         system/
boot/   Config.in.legacy  docs/     Makefile  README           toolchain/
[buildroot-2014.05]$

Dans le répertoire package, je crée habituellement un sous-répertoire correspondant au client pour lequel je développe le projet. Ici, je vais appeler ce sous-répertoire avec le nom de ma société.

[buildroot-2014.05]$ mkdir package/logilin/
[buildroot-2014.05]$

J’ajoute généralement dans ce dossier des sous-répertoires pour chaque développements spécifiques pour le client concerné. En l’occurrence, je vais juste en créer un pour le module rotation-sensor.

[buildroot-2014.05]$ mkdir package/logilin/rotation-sensor-module/
[buildroot-2014.05]$

Dans ce dernier répertoire, j’insère deux fichiers.

  • Un fichier Config.in qui décrit le rôle du module et qui s’intégrera dans le menu de configuration de Buildroot
    config BR2_PACKAGE_ROTATION_SENSOR_MODULE
    	bool "Rotation sensor module"
    	depends on BR2_LINUX_KERNEL
    	help
    	  Kernel module to support rotation sensors
    	  using incremental encoders.
    
    comment "Rotation sensor module requires a linux kernel to be built"
    	depends on !BR2_LINUX_KERNEL
  • Un fichier rotation-sensor-module.mk qui contient les informations pour compiler le projet. C’est surtout ce fichier qui diffère légèrement d’une application classique pour l’espace utilisateur de Linux.
    ################################################################################
    #
    # rotation-sensor-module
    #
    ################################################################################
    
    ROTATION_SENSOR_MODULE_VERSION     = 1.0.0
    ROTATION_SENSOR_MODULE_SITE        = git://github.com/cpb-/rotation-sensor-module.git
    #ROTATION_SENSOR_MODULE_SITE        = $(call github,cpb-,rotation-sensor-module,$(ROTATION_SENSOR_MODULE_VERSION))
    ROTATION_SENSOR_MODULE_SITE_METHOD = git
    ROTATION_SENSOR_MODULE_DEPENDENCIES = linux
    
    define ROTATION_SENSOR_MODULE_BUILD_CMDS
    	$(MAKE) -C $(@D) $(LINUX_MAKE_FLAGS) KERNELDIR=$(LINUX_DIR)
    endef
    
    define ROTATION_SENSOR_MODULE_INSTALL_TARGET_CMDS
    	$(MAKE) -C $(@D) $(LINUX_MAKE_FLAGS) KERNELDIR=$(LINUX_DIR) modules_install
    endef
    
    $(eval $(generic-package))

Au niveau du répertoire package/logilin j’ajoute également deux fichiers qui viendront chercher ceux précédemment décrits.

  • Un fichier Config.in qui correspond au menu des applications spécifiques pour Logilin
    menu "Logilin packages"
      source "package/logilin/rotation-sensor-module/Config.in"
    endmenu

    Bien sûr, j’ai en général plusieurs lignes « source… » pour tous les packages spécifiques du client.

  • Un fichier logilin.mk permettant de compiler tous ces packages.
    ##########################################################
    #
    # Logilin specific packages
    #
    ##########################################################
    
    include package/logilin/*/*.mk

Enfin, le fichier package/Config.in est modifié pour ajouter vers la fin la ligne « source » chargeant package/logilin/Config.in.

menu "Target packages"

source "package/busybox/Config.in"

menu "Audio and video applications"
[...]
source "package/logilin/Config.in"

endmenu

Compilation

Nous allons compiler une image pour une cible bien connue : le Raspberry Pi.

[buildroot-2014.05]$ make raspberrypi_defconfig
mkdir -p /home/cpb/buildroot-2014.05/output/build/buildroot-config/lxdialog
make CC="/usr/bin/gcc" HOSTCC="/usr/bin/gcc" obj=/home/cpb/buildroot-2014.05/output/build/buildroot-config -C support/kconfig -f Makefile.br conf
make[1]: entrant dans le répertoire « /home/cpb/buildroot-2014.05/support/kconfig »
/usr/bin/gcc -DCURSES_LOC="" -DLOCALE  -I/home/cpb/buildroot-2014.05/output/build/buildroot-config -DCONFIG_=\"\"   /home/cpb/buildroot-2014.05/output/build/buildroot-config/conf.o /home/cpb/buildroot-2014.05/output/build/buildroot-config/zconf.tab.o  -o /home/cpb/buildroot-2014.05/output/build/buildroot-config/conf
make[1]: quittant le répertoire « /home/cpb/buildroot-2014.05/support/kconfig »
#
# configuration written to /home/cpb/buildroot-2014.05/.config
#
[buildroot-2014.05]$ make menuconfig

Pendant la configuration de Buildroot, nous examinons le menu package (cliquez sur l’image pour voir le détail).
Menu Buildroot

Nous y trouvons à la fin de la liste le menu « Logilin ».
Menu Package de Buildroot

Nous pouvons alors activer l’option spécifique du codeur incrémental.
Module spécifique dans Buildroot

Il est possible de modifier d’autres paramètres si besoin, voire modifier la configuration du noyau avec

[buildroot-2014.05]$ make linux-menuconfig
   [...]
[buildroot-2014.05]$

Habituellement j’ajoute également un répertoire spécifique board/<nom-client>/<nom-projet>/rootfs dans lequel je place les fichiers de configuration ajoutés ou modifiés. Par exemple, on peut ajouter une ligne dans etc/inittab pour disposer outre la connexion sur le tty1, d’un shell sur le port série du Raspberry Pi. Bien sûr, il faut configurer l’option BR2_ROOTFS_OVERLAY en conséquence.

Nous lançons alors la compilation.

[buildroot-2014.05]$ make

Une fois la compilation terminée, nous pouvons vérifier que notre module a bien été intégré dans l’image de la cible :

[buildroot-2014.05]$ ls output/target/lib/modules/3.12.18-logilin/extra/
rotation-sensor.ko
[buildroot-2014.05]$

Essai

Insérons une carte SD contenant deux partitions nommées respectivement « BOOT » (au format vfat) et « ROOT » (au format ext4).

[buildroot-2014.05]$ cp output/images/rpi-firmware/* /media/cpb/BOOT/
[buildroot-2014.05]$ cp output/images/zImage /media/cpb/BOOT/
[buildroot-2014.05]$ sudo tar x -C /media/cpb/ROOT/ -f output/images/rootfs.tar 
[buildroot-2014.05]$ umount /media/cpb/*
[buildroot-2014.05]$

En plaçant la carte SD dans un Raspberry Pi, nous pouvons vérifier que notre module personnel peut être chargé dans le noyau généré.

Welcome to Buildroot / Raspberry Pi
R-Pi login: root
Password: 
# modprobe rotation-sensor
# lsmod
Module                  Size  Used by    Tainted: G  
rotation_sensor         1691  0 
# ls /dev/ro*
/dev/rotation_sensor
#

 

Suivant :

Précédent :

5 Réponses

  1. digitalLumberjack dit :

    Merci, juste ce qu’il me fallait, j’ai pu reprendre ton makefile et ton package pour builder mon propre module.

    🙂

  2. Tcheva dit :

    Bonjour Christophe. Super tuto, merci !

    Grâce à vous j’ai réussi à ajouter le module avec lequel je veux communiquer (http://www.st.com/web/catalog/sense_power/FM89/SC1449/PF253884) au menuconfig de mon buildroot.
    Par contre, à la compilation je rencontre des soucis, j’ai réutilisé votre makefile en y changeant simplement « obj-m = rotation-sensor.o » par « obj-m = lsm303d.o ».

    Pourriez vous m »éclairer ?

    Merci d’avance

  3. Evrard dit :

    Bonjour,
    J’essaie depuis longtemps de « cross-compiler » un pilote pour mon NAS Synology.
    J’aimerais créer un réseau i2c qui serait pris en charge par le NAS.
    j’ai trouvé le chip ch341 et son driver i2c-ch341-usb adapté par Gunar Schorcht (https://github.com/gschorcht) qui est très bien documenté.

    j’ai sur mon PC: Ubuntu qui tourne sous VirtualBox, j’y ai installé les headers de mon NAS ainsi que sa toolchain.
    solution1:
    J’essaie de compiler le driver de Gunar Schorcht en utilisant son propre Makefile mais j’ai une foule de Warning et d’erreurs.

    Solution2:
    J’ai bien compilé un pilote ch341.c présent dans le Menuconfig d’une version de noyau de mon NAS synology mais la source de i2c-ch341-usb.c ne s’y trouve pas. J’aimerai l’introduire dans la liste et essayer de la compiler par:
    make menuconfig
    make modules
    Est-ce possible ? et si oui comment procéder pour y glisser le i2c-ch341-usb ?
    D’avance merci.

URL de trackback pour cette page