linux Le rôle des nombres majeurs et mineurs dans le pilote de périphérique



file-io linux-kernel (1)

Je pense que l'histoire devrait commencer à partir de ce qui est arrivé quand vous tapez:

mknod /dev/c83 c 8 3

il appellera ext2_mknod ("/ dev", "c83", CHAR, DEV (8, 3)), la plupart des systèmes de fichiers implémentent mknod comme un wrapper de init_special_inode:

void init_special_inode(struct inode *inode, umode_t mode, dev_t rdev)
{
        inode->i_mode = mode;
        if (S_ISCHR(mode)) {
                inode->i_fop = &def_chr_fops;
                inode->i_rdev = rdev;
        } else if (S_ISBLK(mode)) {
                inode->i_fop = &def_blk_fops;
                inode->i_rdev = rdev;
        } else if (S_ISFIFO(mode))
                inode->i_fop = &def_fifo_fops;
        else if (S_ISSOCK(mode))
                inode->i_fop = &bad_sock_fops;
        else
                printk(KERN_DEBUG "init_special_inode: bogus i_mode (%o)\n",
                       mode);
}

Quand vous appelez open ("/ dev / c83"), il va dans la fonction def_chr_fops.chrdev_open, qui remplacera les fops pour le fichier "/ dev / c83" avec les fops que vous avez enregistrés dans cdev_init ():

int chrdev_open(struct inode * inode, struct file * filp)
{
    struct cdev *p;
    ...
    p = inode->i_cdev;
    ...
    filp->f_op = fops_get(p->ops);
    ...
    if (filp->f_op->open) {
        lock_kernel();
        ret = filp->f_op->open(inode,filp);
        unlock_kernel();
    }
    ...
    return ret;
 }

après cela, tout appel système tel que read / write / close va directement aux fonctions des pointeurs enregistrés dans cdev_init ()!

Donc, pour votre première question:

  1. oui, comme vous le voyez dans chrdev_open ().
  2. oui, puisque les fops des devices sont vraiment les mêmes que ceux enregistrés dans cdev_init
  3. joue un rôle important dans open (), puisque open () utilise des paires pour trouver les bons pilotes de périphériques. mais après cela, les autres opérations sur les fichiers, telles que read / write / close (), ne sont plus prises en compte, tout passe par des pointeurs de fonction dans fops résolus dans open ().

J'apprends le pilote de périphérique de Linux et suis resté bloqué sur les nombres mineurs importants. Ce que j'ai jusqu'ici est:

  • Les périphériques sont accessibles via des noms dans le système de fichiers. Ces noms sont appelés en tant que fichiers spéciaux ou fichiers de périphériques ou inodes du système de fichiers.

  • Et chacun des fichiers de périphériques sont associés aux numéros MAJOR et MINOR regroupés dans un type dev_t .

  • Ces numéros sont attribués à l'appareil par la fonction register_chrdev_region

Certaines des questions me troublent encore ...

  1. Est-ce que la structure fops est liée au champ f_ops de la structure du fichier du périphérique lorsque nous initialisons le périphérique comme cdev_init(&c_dev, &fops); ?
  2. Comment un appel à open("/dev/mydev", O_RONLY); appelle réellement la fonction open() des pilotes. Est-ce que les nombres viennent en image ici pour trouver la méthode d'écriture réelle du pilote de périphérique, si oui comment?
  3. Les numéros, majeurs, sont utilisés pour identifier le pilote de périphérique et le fichier mineur sur le périphérique. Quel est le rôle réel de ces nombres lorsque nous effectuons des opérations sur le fichier de périphérique comme open() read() write() etc?




linux-device-driver