Question

J'écris un module de noyau Linux qui doit ouvrir et lire des fichiers. Quel est le meilleur moyen d'y parvenir?

Était-ce utile?

La solution

Puis-je demander pourquoi vous essayez d'ouvrir un fichier?

J'aime suivre le développement de Linux (par curiosité, je ne suis pas un développeur de noyau, je fais de Java), et j’ai déjà vu une discussion sur cette question. J'ai pu trouver un message LKML à ce sujet, mentionnant essentiellement c'est généralement une mauvaise idée. Je suis presque sûr que LWN l’a couvert au cours de la dernière année, mais j’ai du mal à trouver cet article.

S'il s'agit d'un module privé (comme pour certains matériels personnalisés et que le module ne sera pas distribué), vous pouvez le faire, mais j'ai l'impression que si vous allez soumettre votre code à la ligne principale, cela peut ne pas être accepté.

Evan Teran a mentionné sysfs, ce qui me semble une bonne idée. Si vous avez vraiment besoin de créer des objets personnalisés plus difficiles, vous pouvez toujours créer de nouveaux ioctrls.

EDIT:

Bien, j'ai trouvé l'article que je cherchais, il provient du Linux Journal . Cela explique pourquoi ce genre de travail est généralement une mauvaise idée, puis continue en vous expliquant comment le faire de toute façon.

Autres conseils

en supposant que vous puissiez obtenir des pointeurs sur les fonctions relavent du open / read / close , vous pouvez faire quelque chose comme ceci :

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);

vous devez créer le " appel système _ * " fonction des pointeurs que j'ai montré cependant. Je suis sûr qu'il existe un meilleur moyen, mais je pense que cela fonctionnerait.

De manière générale, si vous avez besoin de lire / écrire des fichiers depuis un module du noyau, vous faites quelque chose de mal architecturalement.

Il existe des mécanismes (netlink par exemple - ou simplement l'enregistrement d'un périphérique de type caractère) permettant à un module du noyau de communiquer avec un processus d'assistance de l'espace utilisateur. Ce processus d'assistance utilisateur peut faire ce qu'il veut.

Vous pouvez également implémenter un appel système (ou similaire) pour prendre un descripteur de fichier ouvert dans l’espace utilisateur et le lire / écrire à partir du noyau.

Cela serait probablement plus pratique que d’essayer d’ouvrir des fichiers dans l’espace noyau.

Il y a quelques autres choses qui ouvrent déjà des fichiers depuis l’espace noyau, vous pouvez les regarder (le pilote de boucle vous vient à l’esprit?).

Vous pouvez également trouver des informations sur sys_call_open dans ce module de noyau Linux Guide de programmation .

Le système de fichiers / proc convient également à un usage privé et simple.
http://www.linuxtopia.org/online_books/Linux_Kernel_Mernel_Module_Programming_ >

Tous les développeurs du noyau disent que les entrées / sorties de fichiers de l'espace du noyau sont mauvaises (surtout si vous faites référence à ces fichiers par leurs chemins), mais le noyau principal le fait lorsque vous chargez un microprogramme. Si vous avez juste besoin de lire des fichiers, utilisez la

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

, utilisée par le code du chargeur de firmware, est déclarée dans include / linux / fs.h . Cette fonction renvoie une valeur négative en cas d'erreur.

Je ne suis pas vraiment sûr du but de la variable id à la fin. Si vous regardez le code, il n'est pas vraiment utilisé. Il suffit donc de mettre quelque chose comme READING_FIRMWARE il n'y a pas de guillemets.

buf n'est pas terminé avec null, mais se réfère plutôt à sa taille dans taille . Si vous souhaitez que la terminaison soit nulle, créez une chaîne taille + 1 longue et copiez-la ou réécrivez la fonction kernel_read_file () (utilisée par kernel_read_file_from_path ( ) , défini dans fs / exec.c ) et ajoutez-en un à i_size où la mémoire est allouée. (Si vous voulez faire cela, vous pouvez redéfinir la fonction kernel_read_file () dans votre module avec un nom de fonction différent pour éviter de modifier le noyau entier.)

Si vous devez écrire dans des fichiers, il existe une fonction kernel_write () (analogue à kernel_read () , utilisée par kernel_read_file () et donc aussi par kernel_read_file_from_path () ), mais il n'y a pas de fonction kernel_write_file () ou kernel_write_file_from_path () . Vous pouvez consulter le code du fichier fs / exec.c de l'arborescence du noyau Linux où fichier_read_ernel () et fichier_read_fichier_du_ noyau () sont défini pour écrire vos propres kernel_write_file () et kernel_write_file_from_path () que vous pouvez inclure dans votre module.

Et comme toujours, vous pouvez stocker le contenu d'un fichier dans un pointeur de caractère au lieu d'un pointeur vide avec cette fonction en le diffusant.

scroll top