2016-12-05 2 views
2
#include <linux/module.h> 
#include <linux/kernel.h> 
#include <linux/proc_fs.h> 
#include<linux/sched.h> 
#include <asm/uaccess.h> 
#include <linux/slab.h> 

char *msg; 

ssize_t write_proc(struct file *filp,const char *buf,size_t count,loff_t *offp) 
{ 
    copy_from_user(msg,buf,count); 
    printk(KERN_INFO "%s",msg); 

    return count; 
} 

struct file_operations proc_fops = { 
    write: write_proc 
}; 


int proc_init (void) { 
    proc_create("write",0,NULL,&proc_fops); 

    return 0; 
} 

void proc_cleanup(void) { 
    remove_proc_entry("write",NULL); 
} 

MODULE_LICENSE("GPL"); 
module_init(proc_init); 
module_exit(proc_cleanup); 

Lorsque j'ai utilisé la commande echo 'hello' > /proc/write Rien n'apparaît sur le terminal. Pouvez-vous m'aider à trouver des erreurs dans le code? La chaîne que j'ai écrite dessus devrait apparaître sur le terminal.Création d'une simple entrée de proc en écriture seule dans le noyau

Exemple:

$ echo 'bonjour'>/proc/écriture

bonjour

+2

Vous n'initialisez pas 'msg' mais vous y copiez des données. Cela va planter ... si vous êtes chanceux. – rodrigo

+2

'La chaîne que j'écris dessus devrait apparaître sur le terminal. '- Non,' printk' ne sort pas sur le terminal. Il écrit dans le journal du noyau, que vous pouvez voir via 'dmesg'. – Tsyvarev

+0

Archiver/var/log/messages. –

Répondre

3

Voici quelques modifications simples sur votre code:

#define MSG_SIZE (512) 
static char *msg; 

#define ourmin(a,b) (((a)<(b)) ? (a) : (b)) 

ssize_t write_proc(struct file *filp,const char *buf,size_t count,loff_t *offp) 
{ 
    unsigned long actual_len = ourmin(count, MSG_SIZE-1); 
    memset(msg, 0, MSG_SIZE); 
    copy_from_user(msg, buf, actual_len); 

    printk(KERN_DEBUG "Got: %s",msg); 

    return count; 
} 

int proc_init (void) { 
    // Allocate space for msg 
    if ((msg = kmalloc(MSG_SIZE, GFP_KERNEL)) == NULL) 
    return -ENOMEM; 

    // Should check the output of this too 
    proc_create("write",0,NULL,&proc_fops); 

    return 0; 
} 

void proc_cleanup(void) { 
    remove_proc_entry("write",NULL); 
    kfree(msg); 
} 

je pourrais récupérer la sortie dans le journal du noyau (dmesg par exemple).

+0

Ce serait probablement une bonne idée d'ajouter 'msg [count] = 0;' après le second 'copy_from_user' sinon vous pourriez voir des parties du texte des écritures précédentes. – rodrigo

+0

1. pas besoin d'écrire copy_from_user deux fois 2. il n'y a pas de vérification d'erreur, ce qui signifie en particulier que printk divulgue la mémoire du noyau et peut en principe fonctionner sur une page non mappée et planter 3. le tampon n'est pas nécessairement terminé s'il est copié 4. ENOMEM devrait être -ENOMEM. les erreurs sont négatives. l'argument * buf doit être annoté avec __user. le plus important, bien qu'il soit clair qu'il s'agit d'une affectation et que la familiarité d'OP avec le langage de programmation C et les systèmes de type unix est insuffisante pour accomplir la tâche. On devrait leur conseiller de chercher de l'aide avec leurs camarades. –

+0

@employeeofthemonth: il n'y a pas d'appel deux fois, mais dans le noyau, la macro 'min' ne fonctionnera pas avec une valeur définie statiquement. Par conséquent, au lieu d'en implémenter un autre, j'ai choisi d'utiliser l'instruction if. Merci d'avoir signalé d'autres problèmes que je corrigerai. – Aif