Voici l’appel ioctl
dans l’espace utilisateur:
int ioctl(int fd, int cmd, ...);
Pour autant que je sache, lorsque nous souhaitons effectuer des opérations IO, nous définissons notre propre fonction ioctl
avec un ensemble de requêtes (commandes), affectons notre ioctl
à une structure file_operations comme celle-ci:
struct file_operations fops = { .read = device_read, .write = device_write, .ioctl = device_ioctl, // device_ioctl is our function .open = device_open, .release = device_release, };
Et la fonction device_ioctl
est définie différemment par rapport à l’interface de l’espace utilisateur:
static long device_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
Je pense que sur la base du descripteur de fichier, le kernel peut obtenir la structure de fichier appropriée et appelle l’ ioctl
du périphérique.
Ceci est juste une supposition parce que je ne peux pas trouver la définition de la fonction générique où le kernel sélectionne la fonction ioctl
appropriée en fonction du descripteur de fichier fd
transmis à l’interface ioctl
générique? Il n’y a que 3 définitions ioctl
je peux trouver, mais apparemment ce ne sont que les définitions des périphériques, pas le kernel: ioctl
Regardez dans le code source Linux, fs / ioctl.c ( http://lxr.free-electrons.com/source/fs/ioctl.c )
Là, vous verrez le syscall pour ioctl:
SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)
Cela appelle tour à tour do_vfs_ioctl (), qui appelle vfs_ioctl (), qui appelle ensuite la fonction unlocked_ioctl définie pour ce système de fichiers dans la structure file_operations.
Ce sera votre fonction device_ioctl que vous avez enregistrée.
device_ioctl
est un pointeur de fonction. Le kernel prend simplement fd
comme index pour un tableau de struct file_operations
et appelle le .ioctl
de l’élément correspondant. Le kernel n’a jamais besoin de savoir quelle fonction elle-même est quel périphérique auquel elle fait référence.
C’est la base de “Tout est un fichier”, qui est la devise d’Unix.
Lorsque vous appelez ioctl
vous passez un descripteur de fichier. Vous avez le descripteur de fichier pour ouvrir un fichier de périphérique comme /dev/tty0
:
$ ls -l /dev/tty0 crw--w---- 1 root tty 4, 0 Mar 6 10:47 /dev/tty0 $
Le nombre 4
est le numéro majeur du périphérique qui est encodé dans le module pilote que le kernel doit utiliser.
Le kernel saura quelle fonction ioctl
appeler à cause du descripteur de fichier . Pour pouvoir appeler un ioctl () à partir de l’espace utilisateur, vous devrez ouvrir un fichier pour obtenir le fichier fd
, un fichier / dev / [some_device] dont le pilote implémentera la structure file_operations, comme vous l’avez souligné.