Perché nella maggior parte dei driver di dispositivo tutte le funzioni sono statiche? Poiché le funzioni statiche non sono visibili al di fuori dell'ambito del file. Quindi, come vengono richiamate queste funzioni del driver dalle applicazioni dello spazio utente?Funzioni statiche nel driver di periferica Linux
risposta
Ricorda che in C tutto è indirizzo. Ciò significa che puoi chiamare una funzione se hai l'indirizzo. Il kernel ha una macro chiamata EXPORT_SYMBOL
che fa proprio questo. Esporta l'indirizzo di una funzione in modo che le funzioni del driver possano essere richiamate senza dover inserire dichiarazioni di intestazione poiché tali funzioni a volte non sono note al momento della compilazione. In casi come questo, il qualificatore statico viene creato per garantire che vengano richiamati solo tramite questo metodo e non da altri file che potrebbero includere quel codice del driver (in alcuni casi non è una buona idea includere le intestazioni del codice del driver e chiamarle direttamente) .
EDIT: Poiché è stato sottolineato che non ho coperto lo spazio utente.
Le funzioni del driver solitamente non vengono richiamate direttamente dallo userspace (eccetto per l'implementazione x86 dell'istruzione SYSCALL che fa alcuni piccoli accorgimenti per salvare l'interruttore di contesto a volte). Quindi la parola chiave statica qui non fa differenza. Fa solo una differenza nello spazio del kernel. Come sottolineato da @Cong Wang, le funzioni sono solitamente collocate in una struttura di puntatori di funzione in modo che possano essere richiamate semplicemente facendo in modo che le strutture puntino a questa struttura (come file_ops, scheduler, filesystem, codice di rete, ecc ...).
"chiamato attraverso questo metodo". Qual è questo metodo. intendi la macro EXPORT_SYMBOL? –
@Sibrajas Sì, è soprattutto necessario assicurarsi di non fare affidamento su driver dinamici (che non sono sempre disponibili). –
Questa "risposta" è fasulla ma ha il maggior numero di voti ?! I simboli esportati in un driver sono utilizzabili solo da altre routine del kernel e non sono accessibili dallo spazio utente. Solo perché "conosci" un indirizzo non significa che un programma spaziale utente possa accedere a quella posizione.Linux è un kernel protetto che usa una MMU. – sawdust
Poiché queste funzioni statiche non devono essere utilizzate direttamente all'esterno del modulo. Sono chiamate da altre funzioni nel modulo, tra le quali può essere l'interfaccia a un ioctl oa qualsiasi callback. Questo è il motivo per cui possono essere chiamati dallo spazio utente, sono solo nel percorso della chiamata.
Date un'occhiata al modulo di rete dummy:
dummy_dev_init() è ovviamente statica:
static int dummy_dev_init(struct net_device *dev)
{
dev->dstats = alloc_percpu(struct pcpu_dstats);
if (!dev->dstats)
return -ENOMEM;
return 0;
}
ma è un richiamo di -> ndo_init() che viene chiamato quando si registra questo dispositivo di rete .
static const struct net_device_ops dummy_netdev_ops = {
.ndo_init = dummy_dev_init,
.ndo_uninit = dummy_dev_uninit,
.ndo_start_xmit = dummy_xmit,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_rx_mode = set_multicast_list,
.ndo_set_mac_address = eth_mac_addr,
.ndo_get_stats64 = dummy_get_stats64,
.ndo_change_carrier = dummy_change_carrier,
};
E ovvio nessuno dovrebbe chiamare dummy_dev_init() direttamente.
Il kernel ha migliaia di moduli e sono (o erano) tutti i file oggetto, caricati dinamicamente tramite un processo simile al collegamento - o sono effettivamente collegati-- nell'eseguibile. Riesci a immaginare quante scontro di nomi ci sarebbero se avessero tutti da esportare tutti i loro nomi di funzioni, come è il comportamento C predefinito a meno che non sia specificato static
?
Le applicazioni dello spazio utente non possono chiamare direttamente le funzioni del driver, ma ci sono other ways per interagire.
Chiamandoli direttamente intendevo la chiamata al metodo in fase di compilazione di un driver specifico senza eseguire ioctl o registrarsi come dispositivo o qualcosa del genere. È sempre possibile creare semplicemente un'intestazione o esternalizzare le funzioni e rimuovere la parola chiave statica: P –
Possibile duplicato di: http://stackoverflow.com/questions/12917198/linux-device-driver-program-where-the-program-styles/12923107#12923107 Stai trascurando il fatto che alcune di queste funzioni statiche sono utilizzato nella struttura * operation *, che consente di accedere indirettamente a queste routine statiche tramite un'interfaccia driver standard (ad es. ops di file). – sawdust