2014-04-24 15 views
7

Ho scritto un programma di blocco driver che crea un dispositivo fittizio a blocchi (sbd0). Ho registrato tutte le operazioni del dispositivo per questo dispositivo a blocchi: (fare riferimento a include/linux/blkdev.h a 2.6.32 dei sorgenti del kernel)Perché il kernel utilizza il driver di blocco predefinito al posto del codice del mio driver?

static struct block_device_operations sbd_ops = { 
    .owner   = THIS_MODULE, 
    .open   = sbd_open, 
    .release   = sbd_close, 
    .ioctl   = sbd_ioctl, 
    .getgeo   = sbd_getgeo, 
    .locked_ioctl = sbd_locked_ioctl, 
    .compat_ioctl = sbd_compat_ioctl, 
    .direct_access = sbd_direct_access, 
    .media_changed = sbd_media_changed, 
    .revalidate_disk = sbd_revalidate_disk 
}; 

ho compilato il programma del driver. Ho inserito il modulo e /dev/sbd0 è stato creato. Ora voglio testare il mio codice del driver. Così ho scritto un'applicazione come di seguito.

fd = open("/dev/sbd0", O_RDONLY); 
retval = ioctl(fd, BLKBSZGET, &blksz); //trying to get logical block size 

uscita è: 4096

mi sono chiesto: non ho attuare ioctl per BLKBSZGET. Non ha invocato il mio sbd_ioctl, invece ha usato il driver predefinito e mi ha dato il risultato. Per open, close chiama eseguito sbd_open e sbd_close (che ho implementato). E poi ho provato:

retval = ioctl(fd, HDIO_GETGEO, &geoinfo); 

E 'invocato sbd_getgeo ma ho pensato che sarebbe richiamare sbd_ioctl.

Ecco le mie domande:

  1. ho implementato un autista e ha creato un dispositivo. Se eseguo qualsiasi operazione su quel dispositivo, deve richiamare la mia applicazione driver. Ma come usa alcune delle mie funzioni driver e alcune funzioni driver predefinite?
  2. ioctl(fd, HDIO_GETGEO, ..) non ha richiamato .ioctl chiamata, ma ha invocato .getgeo. Com'è possibile?

risposta

6

Il ioctl dispacciamento viene gestito dalla funzione blkdev_ioctl, che elaborerà alcune delle ioctls direttamente, senza mettere in routine di specifica di guida.

Per HDIO_GETGEO, che chiama direttamente la funzione di guida getgeo (dal kernel 3.13.6, non sembra essere cambiato molto dal 2.6.32):

[...] 
/* 
* We need to set the startsect first, the driver may 
* want to override it. 
*/ 
memset(&geo, 0, sizeof(geo)); 
geo.start = get_start_sect(bdev); 
ret = disk->fops->getgeo(bdev, &geo); /* <- here */ 
[...] 

Per BLKBSZGET, chiama block_size(bdev)), che restituisce semplicemente bdev->bd_block_size.

Troverete blkdev_ioctl in block/ioctl.c se avete bisogno di sapere cosa succede per altri ioctl.

+0

vuoi dire, prima 'ioctl' gestito da' blkdev_ioctl'. Quindi direttamente poche operazioni 'ioctl' gestite da' blkdev_ioctl' e rimanenti saranno gestite dalle mie funzioni driver? – SGG

+0

Sì, è esattamente così. – Mat

+0

Ho visto la definizione di 'blkdev_ioctl'. veramente buono e molto chiaro. Ora voglio vedere come 'ioctl' chiama' blkdev_ioctl'. Voglio vedere il file sorgente. In quale file ottengo questo? – SGG