2013-03-29 3 views
8

Ho due moduli del kernel Linux, uno dei quali può fornire una funzione a un'altra. Ma l'uso di tale funzione non è essenziale, il secondo modulo potrebbe (e dovrebbe) funzionare anche se il primo modulo non è presente.Comunicazione tra moduli nel kernel Linux

Se esporto la funzione dal primo modulo e la uso nel secondo modulo, il secondo modulo dipende da tale simbolo e non può essere caricato senza il primo modulo.

Una delle soluzioni è quella di avere uno script utente che controlli/proc/kallsym per la funzione nel primo modulo, e se è presente, lo script passa il suo indirizzo come parametro al secondo modulo, che poi fa puntatore fuori di esso. Ma non mi piace questa soluzione per ovvi motivi.

Se esiste una soluzione più corretta ed elegante che consenta al secondo modulo di ottenere l'indirizzo di qualche simbolo nel primo modulo, ma evitare una dipendenza forte?

risposta

1

Penso che se il modulo B dipende dal modulo A, il modulo B non può essere caricato correttamente senza che il modulo A sia caricato per primo.

Infatti, solo dopo aver inserito per primo il modulo A, i simboli di cui il modulo B ha bisogno che viene esportato dal modulo A appariranno nel file/proc/kallsym.

La soluzione alla tua situazione: nel modulo B, la funzione module_init() dovrebbe avere alcuni codici per verificare se il modulo A è già presente oppure no, caricare prima A. Ad esempio, request_module() carica A, o crea un metodo più sofisticato per usare try_then_request_module().

+0

Il modulo B deve funzionare anche se non vi è alcun modulo A (supponiamo che A fornisca un'interfaccia per alcuni componenti hardware non presenti su una macchina). – Eugene

+0

C'era un'interfaccia query_module() in 2.4 che faceva quasi esattamente ciò di cui avevo bisogno, ma era stata rimossa in 2.6. Mi chiedo se c'è qualche rimpiazzo ... – Eugene

5

Infine ho trovato la soluzione: kernel ha symbol_get() e symbol_put() che mi danno l'opportunità di cercare un simbolo arbitrario in un altro modulo (deve essere esportato, ovviamente) e impedire al modulo di scaricarsi mentre io sto usando il suo simbolo.

1

ci sono soluzioni più eleganti ma richiedono modifiche al kernel. Fondamentalmente, il kernel è migliorato per ospitare le registrazioni dei moduli. Quando un modulo viene caricato e vuole esporsi ad altri moduli, si registrerà nel kernel con un int ben noto, che è solo un indice nell'array del kernel che memorizza i riferimenti ai moduli registrati. Ora, qualsiasi modulo che vuole acquisire un riferimento ad un altro modulo semplicemente chiederà al kernel un nuovo riferimento a questo modulo - usando lo stesso int conosciuto. Questi nuovi riferimenti devono essere di breve durata (ad esempio si ottiene un riferimento ad esso, ma si inserisce nello stesso contesto). Per consentire connessioni a lunga durata, è necessario creare un protocollo tra i due in modo che quando uno dei due moduli viene scaricato, lui/lei sappia come informare l'altro modulo che sta andando via.