Domanda

Sto scrivendo un modulo del kernel Linux che deve aprire e leggere i file. Qual è il modo migliore per farlo?

È stato utile?

Soluzione

Posso chiederti perché stai cercando di aprire un file?

Mi piace seguire lo sviluppo di Linux (per curiosità, non sono uno sviluppatore del kernel, faccio Java) e ho già discusso di questa domanda. Sono stato in grado di trovare un messaggio LKML su questo, fondamentalmente citando di solito è una cattiva idea. Sono quasi sicuro che LWN lo abbia coperto nell'ultimo anno, ma ho difficoltà a trovare l'articolo.

Se questo è un modulo privato (come per alcuni hardware personalizzati e il modulo non sarà distribuito), puoi farlo, ma ho l'impressione che se hai intenzione di inviare il tuo codice alla linea principale potrebbe non essere accettato.

Evan Teran ha menzionato sysfs, che mi sembra una buona idea. Se hai davvero bisogno di fare cose personalizzate più difficili, puoi sempre creare nuovi ioctrls.

EDIT:

OK, ho trovato l'articolo che stavo cercando, è tratto da Linux Journal . Spiega perché fare questo tipo di cose è generalmente una cattiva idea, poi continua a dirti esattamente come farlo comunque.

Altri suggerimenti

supponendo che tu possa ottenere puntatori ai puntatori della funzione relavent alle chiamate di sistema open / read / close , puoi fare qualcosa del genere :

mm_segment_t fs = get_fs();
set_fs(KERNEL_DS);

fd = (*syscall_open)(file, flags, mode);
if(fd != -1) {
    (*syscall_read)(fd, buf, size);
    (*syscall_close)(fd);
}
set_fs(fs);

dovrai creare il " syscall_ * " puntatori di funzione che ho mostrato però. Sono sicuro che esiste un modo migliore, ma credo che funzionerebbe.

In generale, se hai bisogno di leggere / scrivere file da un modulo del kernel, stai facendo qualcosa di sbagliato dal punto di vista architettonico.

Esistono meccanismi (ad esempio netlink - o semplicemente registra un dispositivo a caratteri) per consentire a un modulo del kernel di comunicare con un processo helper dello spazio utente. Il processo di supporto dello spazio utente può fare quello che vuole.

Potresti anche implementare una chiamata di sistema (o simili) per prendere un descrittore di file aperto nello spazio utente e leggerlo / scriverlo dal kernel.

Questo probabilmente sarebbe più ordinato del tentativo di aprire i file nello spazio del kernel.

Ci sono altre cose che già aprono i file dallo spazio del kernel, potresti guardarli (ti viene in mente il driver del ciclo?).

Puoi anche trovare alcune informazioni su sys_call_open in questo Modulo kernel Linux Guida alla programmazione .

Il filesystem

/ proc è anche buono per uso privato ed è facile.
http://www.linuxtopia.org/online_books/Linux_Kernel_Module_Programming_Guide/x773. >

Tutti gli sviluppatori del kernel affermano che l'I / O dei file dallo spazio del kernel è errato (specialmente se ci si riferisce a questi file tramite i loro percorsi) ma il kernel mainstream lo fa quando si carica il firmware. Se hai solo bisogno di leggere dai file, usa

kernel_read_file_from_path(const char *path, void **buf, loff_t *size, loff_t max_size, enum kernel_read_file_id id)
La funzione

, che è quella che utilizza il codice del caricatore del firmware, dichiarata in include / linux / fs.h . Questa funzione restituisce un valore negativo in caso di errore.

Non sono davvero sicuro del punto della variabile id alla fine, se guardi il codice che non è realmente usato, quindi metti qualcosa come READING_FIRMWARE lì (senza virgolette).

buf non termina con null, ma si riferisce alla sua dimensione in size . Se è necessario che sia terminato con valore null, creare una stringa size + 1 byte e copiarla o riscrivere la funzione kernel_read_file () (utilizzata da kernel_read_file_from_path ( ) , definito in fs / exec.c ) e aggiungine uno a i_size dove è allocata la memoria. (Se vuoi farlo, puoi ridefinire la funzione kernel_read_file () nel tuo modulo con un nome di funzione diverso per evitare di modificare l'intero kernel.)

Se è necessario scrivere su file, esiste una funzione kernel_write () (analoga a kernel_read () , utilizzata da kernel_read_file () e quindi anche di kernel_read_file_from_path () ), ma non esiste kernel_write_file () o kernel_write_file_from_path () . Puoi guardare il codice nel file fs / exec.c nella struttura dei sorgenti del kernel Linux dove kernel_read_file () e kernel_read_file_from_path () sono definito per scrivere le tue funzioni kernel_write_file () e kernel_write_file_from_path () che puoi includere nel tuo modulo.

E come sempre, puoi archiviare il contenuto di un file in un puntatore a caratteri anziché in un puntatore vuoto con questa funzione eseguendo il cast.

scroll top