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

Когда я использовал команду echo 'hello' > /proc/write Ничего не появилось на терминале. Можете ли вы помочь мне найти ошибки в коде? Строка, которую я на нее наложил, должна появиться на терминале.Создание простой записи только для записи в ядре

Пример:

$ эхо 'привет'>/Proc/написать

привет

+2

Вы не инициализируете 'msg', но вы копируете данные на него. Это сбой ... если вам повезет. – rodrigo

+2

'Строка, которую я пишу на ней, должна отображаться на терминале.' - Нет, 'printk' не выводится на терминал. Он записывает в журнал ядра, который вы можете увидеть через 'dmesg'. – Tsyvarev

+0

Регистрация/var/log/messages. –

ответ

3

Вот несколько простых изменений на вашем коде:

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

Я мог бы извлекать выход в журнале ядра (например, dmesg).

+0

Возможно, было бы неплохо добавить 'msg [count] = 0;' после второго 'copy_from_user', иначе вы могли бы увидеть фрагменты текста из предыдущих записей. – rodrigo

+0

1. не нужно писать copy_from_user дважды 2. проверка ошибок отсутствует, что, в частности, означает, что printk раскрывает память ядра и, в принципе, может работать на немаркированной странице и сбой 3. буфер не обязательно завершается нулем при копировании 4. ENOMEM должен быть -ENOMEM. ошибки отрицательны. * buf arg следует аннотировать с помощью __user. самое главное, хотя ясно, что это назначение, а знакомство с языком программирования C и Unix-подобным системам недостаточно для выполнения задачи. Им следует посоветовать обратиться за помощью к сокурсникам. –

+0

@employeeofthemonth: вызов отсутствует дважды, но в ядре макрос 'min' не будет работать со статически определенным значением. Следовательно, вместо того, чтобы внедрять другой, я решил использовать оператор if. Спасибо, что указали другие вопросы, которые я исправлю. – Aif