Salut,
Je vous explique ce titre un peu abstrait par un exemple:
j'ai un module noyau, par exemple l'accès au bus i2c. On va prendre l'i2c, parce que là, je n'ai pas d'erreurs sur la chaine (compilation module, compilation en userland) et tout fonctionne.
Donc j'ai a) un module kernel i2c-dev.ko qui pour chaque bus i2c me crée un periphérique /dev/i2c-x, et des outils qui exploitent /dev/i2c-x (par exemple les i2c-tools, merci pour cette collection trés pratique).
Mon problème est un souci de wrapping. Je souhaite utiliser directement, depuis un module noyau, des opérations plus spécifiques, et exposer cette API.
Mais je n'y arrive pas. Je ne peux pas utiliser open(), ioctl(), read(), write() car je n'ai pas accès à la glibc. Du coup je reste à tourner autour.
J'ai repris i2c-dev, car je peux compter dessus, sur la bonne initialisation du bus. Mais aprés ? Comment effectuer l'ouverture du bus (via - ou pas - son /dev/i2c-0), et écrire dessus ? Quelles APIs utiliser ? Comment suivre ce sur quoi wrappe open(), ioctl() etc ? (pour l'histoire, non, je ne peux pas rester en userland, je suis obligé de traiter ca dans le kernelspace ;) )
Merci ! J'ai essayé quelque mailing-lists (i2c du kernel), mais mon message est inapproprié. Si vous avez des endroits où je puisse trouver de l'aide, je suis preneur !
La solution (MAJ):
Comme le suggère TheBreton, la strcture file_operations permet d'avoir l'équivalence glibc <--> kernel fonction.
Autre point, dans mon cas, j'ai choisi de piloter le bus relativement près du hardware, et j'ai réalisé cela avec i2c_get_adapter() et i2c_transfer(), à l'aide d'une simple structure i2c_msg.
Je peux donc propser dans mon driver des fonctions simples et concises accessible à travers la fops ioctl() de mon module.
Merci !
# Je suis pas sur de comprendre
Posté par TheBreton . Évalué à 3.
Mais il y a une chose de sur, la frontière User/Kernel est inviolable sous linux et tous les échanges User/Kernel doivent se faire par ioctl,open,read,write,select.
Après tous les modules kernel sont dans le même espace, mais chacun n'exporte (ne rend public) que ce qu'il veut bien comme fonction ou variable (voir la doc à propos de EXPORT_SYMBOL() ) .
Donc si deux module doivent inter agir par des fonctions, elles doivent être déclarer public pour que ce soit possible.
[^] # Re: Je suis pas sur de comprendre
Posté par Graveen . Évalué à 3.
Merci à toi.
Comment peux-t-on savoir sur quoi sont wrappées les fonctions open(), ioctl() pour un périphérique donné ?
J'ai lu que cela est détectable à travers un syscall, mais lequel ? http://man7.org/linux/man-pages/man2/syscall.2.html
Mon idée est de savoir exploiter en interne (depuis le kernel space) les accès - dans ce cas au bus i2c - mais comme tu le soulignes, open, ioctl etc ne sont dispos qu'en userland, et j'aurais aimé pouvoir les utiliser à travers des équivalents (parce que c'est quand même vachement pratique) pour exposer les fonctions d'un driver trés ciblé.
[^] # Re: Je suis pas sur de comprendre
Posté par TheBreton . Évalué à 1.
Voir ma réponse dans l'autre thread…
# Simple comme fops
Posté par TheBreton . Évalué à 2. Dernière modification le 31 mai 2013 à 12:10.
C'est linux donc tu as les sources du driver/module en question non ?
En lisant les sources du module I2C il faut chercher la déclaration de la structure file_operations c'est elle qui fait le mapping entre les opérations de fichiers en userland et les fonctions dédié du module
Exemple :
Et mes fonctions
ssize_t my_read (struct file *, char *, size_t, loff_t *);
etc…
PS : Zut pas j'ai cliqué au bon endroit…
# syscalls
Posté par Krunch (site web personnel) . Évalué à 2.
Les appels systèmes sont généralement nommés sys_* dans le noyau. Donc open(2) serait sys_open(). Après, c'est sans doute pas une super idée d'utiliser ça directement depuis le noyau lui même.
pertinent adj. Approprié : qui se rapporte exactement à ce dont il est question.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.