E' tutto per ora, ditemi cosa ne pensate e se volete maggiori informazioni!
gnu modula-2 ed opencm3 sono sviluppati e mantenuti
1- L'architettura del monolitico in Usermode esiste già (cercati L4/Linux e anche Usermode Linux)
applicazioniuserkernel--------------minikernel
applicazioni - userkernel--------------minikernel
2- L'architettura suddetta è una PorcataAbominevole®, si usa soltanto per migrare dei processi legacy, dipendenti da un vecchio kernel monolitico, su una struttura basata su microkernel.
3- Il driver model previsto fa pena: non devono essere i drivers a rompere le scatole al kernel, ma essi dovrebbero registrarsi presso un dispatcher che provvederà a diramare le richieste in base alle "classi di servizio" richieste. In caso di interrupt o syscall, il kernel provvederà a riconoscere la classe di servizio (DMA, VFS, Network, Multimedia, ecc...) e ad inoltrare la richiesta direttamente al driver interessato (che si sarà registrato precedentemente). In questo modo ogni driver avrà almeno un thread, tale thread sarà in wait per un messaggio del kernel (un banale semaforo su una coda di messaggi) e il kernel provvederà a svegliarlo pushando un messaggio sulla coda e sbloccando il relativo semaforo (e rischedulando).
Ho in mente un driver model molto particolare, che sto sviluppando nella mia testa e che in teoria dovrebbe risolvere in modo efficiente il problema dei driver in user space. Si basa sul concetto di "attore", cioè un fantoccio in kernel mode che possiede i meccanismi per interagire con l'hardware (un attore per il bus PCI, uno per il bus AGP, uno per la RS232, ecc...) ma non le policies.Il driver in User Mode si occupa di scrivere il "copione" (il protocollo di comandi necessari per compiere una determinata operazione) e comunica questo copione al suo attore corrispondente.Un driver può a sua volta registrarsi come attore. In tal caso girerà sempre in User Mode.
Tale architettura si presta chiaramente ad una modellazione ad oggetti, ed è pensata infatti per tale tipo di implementazione.
Data la moltitudine di device che ci saranno ti consiglio di creare una classe Device e una classe DeviceFrames che conterrà la lista dei device type presenti nel kernel (non so se conosi la tecnica).
Le classi IS le devi organizzare come single-inheritance (gerarchico), l'object composition HAS è safe usarlo con il multiple inheritance bloccato ad un livello.
In ogni caso l'object composition è una tecnica alternativa di encapsulation all'inheritance, quindi ciò che dici tu non si può fare (il composed object non può vedere in alcun modo gli state di chi lo possiede).
E' meglio organizzarlo come independent component del kernel (un servizio) in cui tu registri i Device (ecco che qui la classe DeviceFrames ti viene in aiuto). Mettere l'handler come componente della classe device la vedo problematica come soluzione, anche perché per gli usi futuri che farai degli ISR ti servirebbe osservare gli state anche di altri device
No, non ti conviene mettere in alcun modo quegli oggetti in relazione, perché poi trovi difficoltà a gestire casi come per esempio più device nello stesso interrupt,
Il problema è che l'interrupt handler dovrebbe avere certi gradi di libertà sui device, non sottostare ai device.
Come ho detto prima conviene che gestisci l'interrupt handler come un componente indipendente del kernel in cui registri i device. Ogni interrupt handler all'interno del componente ha un DeviceFrame con tutti i device che dipendono da quell'interrupt.Le comunicazioni tra device ed interrupt handler avvengono con un metodo Signal o Notify (scegli tu) del device, in cui (come parametro di output) comunica quello che deve comunicare all'interrupt handler.A proposito di polling dato che con gli interrupt li userai tantissimo conviene che gestisci il tuo design OOP sugli interrupt in maniera diversa. Creare una classe KernelEvent (ti servirà parecchio in futuro) da cui derivare poi InterruptEvent. I device la comunicazione a segnali la gestiranno tramite InterruptEvent dichiarandone una propria, per esempio InterruptEventKeyboard (per la tastiera), che in più avrà i flagset o quel che sia che serviranno all'interrupt handler della tastiera.Il tuo componente per la gestione degli interrupt handler dovrà solo interpretare gli InterruptEvent dei vari device registrati.
Non c'eri ai tempi di Windows 95 che non sapeva gestire gli IRQ condivisi?
Qui sono stato poco chiaro io intendo che non è il device che deve stabilire la comunicazione, ma qualcun altro.Che l'handler sia specifico per ogni periferica è chiaro, io intendevo che chi gestisce l'interrupt deve essere uno solo.
Su FreeBSD la componente del kernel che gestisce gli interrupt è un framework basato sui bus ed i resource, che sono molto generici. Questo permette di separare i dettagli dell'architettura dalla periferica e dal tipo di comunicazione (pci, usb, etc).
Quando scrivi un driver su freebsd, l'interrupt handler lo scrivi tu ma poi viene gestito dal framework del bus:http://www.freebsd.org/cgi/man.cgi?query=bus_setup_intrint BUS_SETUP_INTR(device_t dev, device_t child, struct resource *irq, int flags, driver_filter_t *filter, driver_intr_t *ithread, void *arg, void **cookiep);con BUS_ALLOC_RESOURCE crei e riservi una risorsa interrupt e dopo gli assegni l'handler con il parametro driver_intr_t *ithread, la comunicazione verrà gestita dal bus manager.
Io sono newbie sul fronte sistema operativi, ho letto qualche libro ma non ho mai implementato nulla di serio.
Secondo me dovresti basarti su qualche driver model esistente,
magari quello che ti piace di più ed ha il più basso rapporto pregi/difetti
Ho dato un'occhiata anche a WDF, che da un esempio di driver base non sembrava male, ma non mi piace il fatto che hanno progettato un sistema object-oriented e poi gli hanno dato un'interfaccia in C. D'accordo che volevano prendere la maggioranza dei programmatori, ma non penso sarebbe stato un trauma per i programmatori C imparare quelle 4 cose di C++ necessarie per scrivere il driver.
Perché non c'è solo il C++. Un'interfaccia "C" è utilizzata come "lingua franca" per esporre API "consumabili" da tutti gli altri linguaggi.Se, invece, definisci un'interfaccia C++ per esporre le tue API, queste saranno "consumabili" da ben pochi linguaggi.
Delphi o FreePascal.