Qual è la differenza tra driver del kernel e moduli del kernel?


67

Quando faccio un lspci -kKubuntu sul mio kernel 3.2.0-29-generico posso vedere qualcosa del genere:

01:00.0 VGA compatible controller: NVIDIA Corporation G86 [Quadro NVS 290] (rev a1)
    Subsystem: NVIDIA Corporation Device 0492
    Kernel driver in use: nvidia
    Kernel modules: nvidia_current, nouveau, nvidiafb

C'è un driver del kernel nvidiae moduli del kernel nvidia_current, nouveau, nvidiafb.

Ora mi chiedevo quale potrebbe essere la differenza tra driver del kernel e moduli del kernel?

Risposte:


78

Un modulo del kernel è un po 'di codice compilato che può essere inserito nel kernel in fase di esecuzione, come con insmodo modprobe.

Un driver è un po 'di codice che viene eseguito nel kernel per parlare con qualche dispositivo hardware. "Guida" l'hardware. La maggior parte di ogni bit di hardware nel tuo computer ha un driver associato.¹ Una gran parte di un kernel in esecuzione è il driver code.²

Un driver può essere compilato staticamente nel file del kernel sul disco.³ Un driver può anche essere creato come modulo del kernel in modo che possa essere caricato in modo dinamico in un secondo momento. (E quindi forse scaricato.)

La pratica standard è quella di costruire driver come moduli del kernel ove possibile, piuttosto che collegarli staticamente al kernel, poiché ciò offre maggiore flessibilità. Vi sono buoni motivi per non:

  • A volte un determinato driver è assolutamente necessario per aiutare il sistema ad avviarsi. Ciò non accade tutte le volte che potresti immaginare, grazie alla funzione initrd .

  • I driver creati staticamente possono essere esattamente ciò che si desidera in un sistema con ambito statico, ad esempio un sistema incorporato . Vale a dire, se sai in anticipo esattamente quali driver saranno sempre necessari e che ciò non cambierà mai, hai una buona ragione per non preoccuparti dei moduli dinamici del kernel.

  • Se si crea staticamente il kernel e si disabilita la funzione di caricamento del modulo dinamico di Linux, si impedisce la modifica in fase di esecuzione del codice del kernel. Ciò fornisce ulteriore sicurezza e stabilità a spese della flessibilità.

Non tutti i moduli del kernel sono driver. Ad esempio, una funzionalità relativamente recente nel kernel di Linux è che è possibile caricare un pianificatore di processo diverso . Un altro esempio è che i tipi più complessi di hardware hanno spesso più livelli generici che si trovano tra il driver hardware di basso livello e l'area utente, come il driver USB HID , che implementa un particolare elemento dello stack USB , indipendentemente dall'hardware sottostante.


asides:

  1. Un'eccezione a questa affermazione ampia è il chip della CPU, che non ha "driver" di per sé . Il computer potrebbe anche contenere hardware per il quale non si dispone di driver.

  2. Il resto del codice in un kernel del sistema operativo fornisce servizi generici come la gestione della memoria , IPC , pianificazione , ecc. Questi servizi possono servire principalmente le applicazioni di terra dell'utente , come con gli esempi precedentemente collegati, oppure possono essere servizi interni utilizzati da driver o altri intra- infrastruttura del kernel.

  3. Quello in /boot, caricato nella RAM all'avvio dal caricatore di avvio nelle prime fasi del processo di avvio .


1
I moduli possono essere filesystem, protocolli di rete, funzionalità firewall e molto altro. Alcuni hardware (ad es. Schede WiFi) richiedono una pila di moduli, alcuni offrono un'infrastruttura generale mentre altri gestiscono l'hardware stesso.
vonbrand,

1
Questo è un buon schema generale, ma avevo esattamente la stessa domanda dell'OP, quindi ho trovato questa risposta e ancora non sapevo perché il "driver in uso" fosse diverso dai "moduli". Al contrario, la risposta di @Jim Paris è corretta. Da man lspci: "-k Mostra i driver del kernel che gestiscono ogni dispositivo e anche i moduli del kernel in grado di gestirlo ." Si potrebbe leggere come: "Mostra il driver attualmente / effettivamente gestisce il dispositivo e anche tutti i moduli che potrebbero / sono destinati a gestirlo ".
Binarus,

Se conosci Windows: un modulo è molto simile a una DLL. Su unix, un modulo è simile a un oggetto condiviso, ma un modulo è solo per il kernel. Un modulo collegato dinamicamente può contenere driver. Un kernel può contenere driver collegati staticamente. Un modulo è diverso da una DLL (o .so) perché il kernel ha requisiti specifici per il modo in cui le cose vengono caricate dinamicamente.
robocat

18

Per rispondere alla tua domanda specifica lspcisull'output, la riga "driver del kernel" si riferisce a quale driver è attualmente associato alla scheda, in questo caso il nvidiadriver proprietario . La riga "moduli del kernel" elenca tutti i driver noti per essere in grado di associarsi a questa scheda. Qui, il driver proprietario mostra un nome diverso, probabilmente a causa di come lspcitrovato il driver e il suo nome file rispetto al nome codificato nel driver stesso.


Grazie - mi ha aiutato. Se solo avessi pubblicato man lspci- dice esattamente quello che hai scritto.
Binarus,

5

Secondo questo bel tutorial :

... un tipo di modulo è il driver del dispositivo, che consente al kernel di accedere all'hardware collegato al sistema.

Quindi, se proviamo a disegnare un albero, avremo "Device driver" che eredita dal modulo (si estende) e che ha caratteristiche più specifiche, tra le quali troviamo "accesso all'hardware" ...


Questo è solo parzialmente corretto. Il driver è un oggetto di una classe nella gerarchia (sì, il design interno di Linux, come la maggior parte dei sistemi operativi attuali, è orientato agli oggetti). Ma detto driver potrebbe essere un modulo (caricabile in fase di esecuzione) o compilato nel kernel. Non c'è (o molto poca) differenza tra le alternative, per quanto riguarda il codice.
vonbrand,

4

Un modulo kernel potrebbe non essere affatto un driver di dispositivo.

"Driver del kernel" non è un termine ben definito, ma proviamolo.

Questo è un modulo del kernel che non guida alcun hardware e quindi non può essere ragionevolmente considerato un "driver di periferica":

#include <linux/module.h>
#include <linux/kernel.h>

MODULE_LICENSE("GPL");

static int myinit(void)
{
    printk(KERN_INFO "hello init\n");
    return 0;
}

static void myexit(void)
{
    printk(KERN_INFO "hello exit\n");
}

module_init(myinit)
module_exit(myexit)

Dopo la compilazione, puoi usarlo con:

insmod hello.ko

e stampa hello initsu dmesg.

Esistono, tuttavia, moduli del kernel che non sono driver di dispositivo, ma sono effettivamente utili, ad esempio moduli che espongono le informazioni di debug / prestazioni del kernel.

I driver di dispositivo sono generalmente anche moduli del kernel.

Un esempio di qualcosa che è un "driver di dispositivo" è un po 'più difficile da generare, poiché richiede un hardware da guidare e le descrizioni dell'hardware tendono ad essere complicate.

Utilizzando QEMU o altri emulatori, tuttavia, possiamo costruire modelli software di hardware reale o semplificato, il che è un ottimo modo per imparare a parlare con l'hardware. Ecco un semplice esempio di un driver di dispositivo PCI minimo: https://github.com/cirosantilli/linux-kernel-module-cheat/blob/6788a577c394a2fc512d8f3df0806d84dc09f355/kernel_module/hello.c

Vediamo quindi che in x86, parlare con l'hardware si riduce a:

Queste operazioni non possono in genere essere eseguite da userland, come spiegato in: Qual è la differenza tra spazio utente e spazio kernel? Vi sono tuttavia alcune eccezioni: https://stackoverflow.com/questions/7986260/linux-interrupt-handling-in-user-space .

Il kernel offre quindi API di livello superiore per rendere tale interazione hardware più semplice e portatile:

  • request_irq gestire gli interrupt
  • ioreadX e mappatura della memoria IO
  • interfacce di livello ancora più elevato per protocolli popolari come PCI e USB

0

La mia risposta andrà con Jim. Un driver del kernel è un programma (modulo del kernel) progettato per guidare un componente hardware. L'output di lspci dice che nvidia è il driver del kernel in quanto è il loadedmodulo per il dispositivo. Insieme ad esso arrivano altri moduli kernel disponibili.

Aggiungerò che i comandi in linux per elencare e rimuovere i driver sono lsmode rmmodrispettivamente. Che dice il modulo elenco e rimuovere il modulo.


0

Tutti i driver sono moduli. Non tutti i moduli sono driver.

I moduli possono essere inseriti in fase di esecuzione. Moduli / Driver possono essere compilati staticamente insieme al kernel.

Iniziale modulo tipico ha

module_init(init_fn);
init_fn()
{
   /* some code */
}

Lo stesso modulo può essere trasformato in un driver

module_init(init_fn);
init_fn()
{
   device_register(&device);
   /* some code */
}

8
I driver non sono sempre moduli, possono essere inclusi nell'immagine del kernel principale.
Gilles 'SO- smetti di essere malvagio' il

3
@Prabagaran: "Tutti i driver sono moduli. Tutti i moduli non sono driver." Questo è contraddittorio. In termini matematici, quello che stai dicendo è D -> M e M ->! D. Ciò consente D e! D.
Francesco Turco,

2
Penso che significhi "Tutti i driver sono moduli. Non tutti i moduli sono driver".
Renan,

4
@Renan: Sarebbe corretto, ma se guardi la cronologia delle modifiche per questa risposta qualcuno ha già provato a correggere l'errore e l'autore l'ha ripristinata. Normalmente vorrei solo modificare per correggere l'errore e andare avanti, ma in questo caso ho -1 perché è solo sbagliato e confonde il problema.
Caleb,

Come ricordo (non scherziamo da un po ') ci sono alcuni driver che non possono essere costruiti come moduli caricabili. Mi sembra di ricordare altri che possono essere gestiti solo come moduli.
vonbrand,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.