2013-03-08 18 views
24

Sto cercando di scrivere un driver PWM. So che ci sono due modi in cui possiamo controllare un driver hardware:Spazio utente vs driver di spazio kernel

  1. Driver spazio utente.
  2. kernel driver di spazio

Se in generale (non considerare un caso pilota PWM) dobbiamo prendere una decisione se andare per spazio utente o un driver kernel space. Quindi quali fattori dobbiamo prendere in considerazione oltre a questi?

  1. Il driver dello spazio utente può direttamente la memoria di mmap()/dev/mem nel proprio spazio di indirizzamento virtuale e non è necessario il cambio di contesto.
  2. Il driver userspace non può avere implementatori di interrupt implementati (devono interrogare per l'interrupt).
  3. Il driver dello spazio utente non può eseguire DMA (dato che la memoria DMA può essere allocata dallo spazio del kernel).
+1

Sicurezza: autorizzazioni file del controllo del nodo dispositivo che gli utenti possono aprire/leggere/scrivere sul dispositivo. Le operazioni sui file negano o consentono operazioni simultanee. – sawdust

+1

La decisione può dipendere in gran parte da cosa si sta facendo da PWM e dall'hardware. –

risposta

31

Da questi tre fattori che hai elencato solo il primo è effettivamente corretto. Per il resto, non proprio. È possibile che un codice spaziale utente esegua operazioni DMA, nessun problema. Ci sono molte aziende di dispositivi hardware che impiegano questa tecnica nei loro prodotti. È anche possibile avere un'applicazione di spazio utente basata su interrupt, anche quando tutto l'I/O viene eseguito con un bypass completo del kernel. Certo, non è così facile semplicemente fare un mmap() su /dev/mem.

Si dovrebbe avere una minima parte del driver nel kernel - che è necessaria al fine di fornire il vostro spazio utente con un minimo di cui ha bisogno dal kernel (perché se ci pensate - /dev/mem è anche supportato da un driver di dispositivo di carattere).

Per DMA, in realtà è troppo dannatamente facile - tutto ciò che dovete fare è quello di gestire mmap richiesta e mappare un DMA tampone nello spazio utente. Per gli interrupt - è un po 'più complicato, l'interrupt deve essere gestito dal kernel, non importa cosa, tuttavia, il kernel potrebbe non funzionare e semplicemente riattivare il processo che chiama, per esempio, epoll_wait(). Un altro approccio è quello di fornire un segnale al processo come fatto da DOSEMU, ma che è molto lento e non è raccomandato.

Come per la tua domanda, un fattore da tenere in considerazione è la condivisione delle risorse. Finché non è necessario condividere un dispositivo su più applicazioni e non c'è nulla che non si possa fare nello spazio utente: andare nello spazio utente. Probabilmente risparmierai un sacco di tempo durante il ciclo di sviluppo poiché scrivere codice utente dello spazio è estremamente semplice. Quando, tuttavia, due o più applicazioni devono condividere il dispositivo (o le sue risorse), è probabile che spenderai una quantità enorme di tempo per renderlo possibile - immagina più processi di forking, crash, mapping (lo stesso?) Memoria simultaneamente ecc. E dopo tutto, IPC viene generalmente eseguito attraverso il kernel, quindi se l'applicazione dovrebbe iniziare a "parlare" tra loro, le prestazioni potrebbero peggiorare notevolmente. Questo è ancora fatto nella vita reale per alcune applicazioni critiche per le prestazioni, però, ma non voglio entrare in questi dettagli.

Un altro fattore è l'infrastruttura del kernel. Diciamo che vuoi scrivere un driver di dispositivo di rete. Non è un problema farlo nello spazio utente. Tuttavia, se lo fai, dovresti scrivere anche uno stack di rete completo in quanto non sarà possibile per l'utente predefinito di Linux che risiede nel kernel.

Direi di andare per lo spazio utente se è possibile e la quantità di sforzi per far funzionare le cose è inferiore alla scrittura di un driver del kernel e tenere presente che un giorno potrebbe essere necessario spostare il codice nel kernel . In effetti, è una pratica comune avere lo stesso codice compilato sia per lo spazio utente che per lo spazio del kernel a seconda che alcune macro siano definite o meno, perché testare nello spazio utente è molto più piacevole.

+0

Ottima risposta. Stavo cercando queste informazioni e la tua risposta è stata molto utile.! –

+0

Tuttavia epoll ha un meccanismo veloce, infine è una struttura di polling non un gestore di interrupt. Potrebbe causare problemi con operazioni a tempo critico. – obayhan

6

Un'altra considerazione: è molto più facile eseguire il debug dei driver spazio utente. È possibile utilizzare gdb, valgrind, ecc. Heck, non è nemmeno necessario scrivere il driver in C.

C'è una terza opzione oltre al solo spazio utente o driver di spazio del kernel: alcuni di entrambi. Puoi fare solo le cose dello spazio del kernel solo in un driver del kernel e fare tutto il resto nello spazio utente. Potrebbe non essere nemmeno necessario scrivere il driver dello spazio del kernel se si utilizza il framework driver UIO Linux (vedere https://www.kernel.org/doc/html/latest/driver-api/uio-howto.html).

Ho avuto la fortuna di scrivere un driver in grado DMA quasi completamente nello spazio utente. UIO fornisce l'infrastruttura in modo che tu possa semplicemente leggere/selezionare/epoll su un file per attendere un interrupt.

È necessario essere consapevoli delle implicazioni di sicurezza della programmazione dei descrittori DMA dallo spazio utente: a meno che non si disponga di una protezione nel dispositivo stesso o in un IOMMU, il driver dello spazio utente può far leggere o scrivere su qualsiasi indirizzo del dispositivo nella memoria fisica.

Problemi correlati