2016-12-05 4 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); 

Wenn ich den Befehl echo 'hello' > /proc/write verwendet, erscheint nichts am Terminal. Kannst du mir helfen, Fehler im Code zu finden? Die Zeichenfolge, auf der ich mich geschrieben habe, sollte auf dem Terminal erscheinen.Erstellen eines einfachen Nur-Schreib-Proc-Eintrags im Kernel

Beispiel:

$ echo 'Hallo'>/proc/schreiben

hallo

+2

Sie initialisieren 'msg' nicht, aber Sie kopieren Daten dorthin. Das wird zusammenbrechen ... wenn du Glück hast. – rodrigo

+2

'Die Zeichenfolge, die ich darauf geschrieben habe, sollte am Terminal angezeigt werden. - Nein,' printk' wird nicht am Terminal ausgegeben. Es schreibt in das Kernel-Protokoll, das Sie über 'dmesg' sehen können. – Tsyvarev

+0

Einchecken/var/log/messages. –

Antwort

3

Hier sind einige einfache Änderungen an Ihrem 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); 
} 

ich die Ausgabe abrufen konnte im Kernel-Protokoll (dmesg zum Beispiel).

+0

Es wäre wahrscheinlich eine gute Idee, 'msg [count] = 0;' nach dem zweiten 'copy_from_user' hinzuzufügen, sonst könnten Sie Teile des Textes aus früheren Schreibvorgängen sehen. – rodrigo

+0

1. keine Notwendigkeit, copy_from_user zweimal zu schreiben 2. es gibt keine Fehlerprüfung, was insbesondere bedeutet, dass der printk Kernel-Speicher offenlegt und im Prinzip in eine nicht zugeordnete Seite laufen und abstürzen kann 3. der Puffer ist nicht unbedingt null terminiert, wenn kopiert 4. ENOMEM sollte -ENOMEM sein. Fehler sind negativ. Der * buf arg sollte mit __user kommentiert werden. Vor allem aber ist klar, dass dies eine Aufgabe ist und OPs Vertrautheit mit der C-Programmiersprache und unixartigen Systemen nicht ausreicht, um die Aufgabe zu erfüllen. Sie sollten darauf hingewiesen werden, Hilfe bei Kommilitonen zu suchen. –

+0

@employeeofthemonth: Es gibt keinen Aufruf zweimal, aber im Kernel funktioniert das 'min' Makro nicht mit einem statisch definierten Wert. Anstatt eine andere zu implementieren, entschied ich mich für die if-Anweisung. Danke, dass Sie auf andere Probleme hingewiesen haben, die ich korrigieren werde. – Aif

Verwandte Themen