Descrizione
Iniziamo la discussione con il driver del personaggio in Linux. Il kernel classifica i driver in tre categorie:
Driver di personaggi - Questi sono i driver che non hanno troppi dati da affrontare. Pochi esempi di driver di caratteri sono driver touch screen, driver UART, ecc. Tutti questi sono i driver di caratteri poiché il trasferimento dei dati viene eseguito tramite carattere per carattere.
Blocca i conducenti - Questi sono i driver che si occupano di troppi dati. Il trasferimento dei dati viene eseguito il blocco per blocco poiché è necessario trasferire troppi dati. Esempio di conducenti a blocchi sono SATA, NVME, ecc.
Driver di rete - Questi sono i driver che funziona nel gruppo di rete di driver. Qui, il trasferimento dei dati viene eseguito sotto forma di pacchetti di dati. I driver wireless come Atheros rientrano in questa categoria.
In questa discussione, ci concentreremo solo sul driver del personaggio.
Ad esempio, prenderemo le semplici operazioni di lettura/scrittura per comprendere il driver del personaggio di base. Generalmente, qualsiasi driver di dispositivo ha queste due operazioni minime. L'operazione aggiuntiva potrebbe essere aperta, chiusa, IOCTL, ecc. Nel nostro esempio, il nostro driver ha la memoria nello spazio del kernel. Questa memoria è allocata dal driver del dispositivo e può essere considerata come memoria del dispositivo poiché non esiste un componente hardware. Il driver crea l'interfaccia del dispositivo nella directory /dev che può essere utilizzata dai programmi di spazio utente per accedere al driver ed eseguire le operazioni supportate dal driver. Per il programma utenti, queste operazioni sono proprio come qualsiasi altra operazione di file. Il programma di spazio utente deve aprire il file del dispositivo per ottenere l'istanza del dispositivo. Se l'utente desidera eseguire l'operazione di lettura, la chiamata di sistema di lettura può essere utilizzata per farlo. Allo stesso modo, se l'utente desidera eseguire l'operazione di scrittura, la chiamata di sistema di scrittura può essere utilizzata per ottenere l'operazione di scrittura.
Driver del personaggio
Consideriamo di implementare il driver del personaggio con le operazioni di dati di lettura/scrittura.
Iniziamo con l'istanza dei dati del dispositivo. Nel nostro caso, è "struct cdrv_device_data".
Se vediamo i campi di questa struttura, abbiamo CDEV, buffer di dispositivi, dimensioni del buffer, istanza di classe e oggetto dispositivo. Questi sono i campi minimi in cui dovremmo implementare il driver del personaggio. Dipende dall'implementatore da quali campi aggiuntivi vuole aggiungere per migliorare il funzionamento del driver. Qui, cerchiamo di ottenere il funzionamento minimo.
Successivamente, dovremmo creare l'oggetto della struttura dei dati del dispositivo. Usiamo le istruzioni per allocare la memoria in modo statico.
struct cdrv_device_data char_device [cdrv_max_minors];
Questa memoria può anche essere assegnata dinamicamente con "kmalloc". Manteniamo l'implementazione il più semplice possibile.
Dovremmo prendere l'implementazione delle funzioni di lettura e scrivere. Il prototipo di queste due funzioni è definito dal framework del driver del dispositivo di Linux. L'implementazione di queste funzioni deve essere definita dall'utente. Nel nostro caso, abbiamo considerato quanto segue:
Leggi: l'operazione per ottenere i dati dalla memoria del driver allo spazio utenti.
static ssize_t cdrv_read (file struct *, char __user *user_buffer, size_t size, loff_t *offset);
Scrivi: l'operazione per archiviare i dati alla memoria del driver dallo spazio utenti.
static ssize_t cdrv_write (file struct *, const char __user *user_buffer, size_t size, loff_t *offset);
Entrambe le operazioni, lettura e scrittura, devono essere registrate come parte di Struct File_Operations CDRV_FOPS. Questi sono registrati nel framework del driver del dispositivo Linux in init_cdrv () del driver. All'interno della funzione init_cdrv (), vengono eseguite tutte le attività di configurazione. Pochi compiti sono i seguenti:
Il codice di esempio completo per il driver del dispositivo di caratteri di base è il seguente:
#includereCreiamo un makefile di esempio per compilare il driver dei caratteri di base e l'app di prova. Il nostro codice del driver è presente in CRDV.C e il codice dell'app di test è presente in CDRV_APP.C.
OBJ-M+= CDRV.oDopo che l'emissione è stata effettuata al makefile, dovremmo ottenere i seguenti registri. Otteniamo anche il CDRV.KO e eseguibile (CDRV_APP) per la nostra app di test:
root@haxv-srathore-2:/home/cienauser/kernel_articles# makeEcco il codice di esempio per l'app di test. Questo codice implementa l'app di test che apre il file del dispositivo creato dal driver CDRV e scrive i "dati di test" ad esso. Quindi, legge i dati dal driver e li stampa dopo aver letto i dati da stampare come "dati di prova".
#includereUna volta che abbiamo tutte le cose in atto, possiamo usare il seguente comando per inserire il driver di caratteri di base sul kernel Linux:
root@haxv-sratore-2:/home/cienauser/kernel_articles# insmod cdrv.koDopo aver inserito il modulo, otteniamo i seguenti messaggi con DMESG e creiamo il file del dispositivo creato in /dev as /dev /cdrv_dev:
root@haxv-srathore-2:/home/cienauser/kernel_articles# dmesgOra, eseguire l'app di test con il seguente comando nella shell Linux. Il messaggio finale stampa i dati di lettura dal driver che è esattamente lo stesso di quello che abbiamo scritto nell'operazione di scrittura:
root@haxv-sratore-2:/home/cienauser/kernel_articles# ./cdrv_appAbbiamo alcune stampe aggiuntive nel percorso di scrittura e lettura che può essere vista con l'aiuto del comando dmesg. Quando emettiamo il comando DMESG, otteniamo il seguente output:
root@haxv-srathore-2:/home/cienauser/kernel_articles# dmesgConclusione
Abbiamo esaminato il driver di caratteri di base che implementa le operazioni di scrittura e lettura di base. Abbiamo anche discusso del campione makefile per compilare il modulo insieme all'app di test. L'app di test è stata scritta e discussa per eseguire le operazioni di scrittura e lettura dallo spazio utente. Abbiamo anche dimostrato la compilation e l'esecuzione del modulo e dell'app di test con registri. L'app di test scrive pochi byte di dati di test e poi li legge indietro. L'utente può confrontare sia i dati per confermare il funzionamento corretto del driver e dell'app di test.