2013-07-28 46 views
3

我试图在/proc中创建一个条目,以便我可以控制我的内核模块。我想我得到了write部分,但我无法弄清楚read部分应该如何工作。从LKM创建/ proc中的条目

static char proc_data[1]; 

static ssize_t read_proc(struct file *file, char __user *buf, size_t count, loff_t *pos){ 
    int ret; 
    if(pos > 0){ 
     ret = 0; 
    }else{ 
     memcpy(buf, proc_data, 1); 
     ret = 1; 
    } 
    return ret; 
} 

static ssize_t write_proc(struct file *file, const char __user *buf, size_t count, loff_t *pos){ 

    if(count > 2) 
     return -EINVAL; 

    if(copy_from_user(proc_data, buf, 1)) 
     return -EFAULT; 

    if(strcmp("1", proc_data) == 0){ 
     //Do something 
    }else if(strcmp("0", proc_data) == 0){ 
     //Undo something 
    } 

    return count; 
} 

如果我回到1从read_proc,如果我的猫我的/proc项,它不会停止输出相同的值。如果我返回0,它不会输出任何东西。所以我猜我应该第一次返回1,然后返回0,但我不知道如何。

+0

也许你应该打印你从第一次和后续调用中收到的参数...也许具体是偏移参数。他们不是0 /非零,因为你的代码似乎已经解决了? – mah

+0

@mah我想到了这一点,但我看不到它们之间的任何关系,因为count是65535并且是空的。 – alexandernst

+0

我希望在所有情况下(无论调用者要求什么)在块效率上都会得到相同的大小计数,并且随着每次后续调用都会从同一个开放位置增加到该计数大小。请记住,内核调用非常昂贵,因此系统希望将其最小化,并将通过大型缓冲区来实现,从而最大限度地减少要调用的调用数量。 – mah

回答

3

.read.write回调函数中,通常需要在返回前更新loff_t *pos。 如果您的模块读取或写入了count字节,则按该数量增加*pos

此外,请注意,当.read回调返回0时,它表示一个EOF。如果它永远不会返回0,那么系统将无限期地循环尝试“当文件读取到最后”时,当您的文件为cat时。这就是为什么第一次返回1,然后是0工作。

+0

当我的回调被调用时,'''pos'''应该是0,对吧?我得到一个非常随机的大负数(大约-131940446716000,给/拿100000)。我在我的'''printk'''中使用''''%lld和(long long int)pos''',这是否正确? – alexandernst

+0

@alexandernst,你打印'pos'或'* pos'?我犯了很多次这样的错误。你所描述的看起来更像是一个指针,如果用有符号整数表示,内核中的结构地址是负数,至少在x86上。我期望在回调的第一次调用时,* pos是0。 – Eugene

+0

糟糕...我正在印刷'''pos'''而不是'''pos'''!多么愚蠢的错误。谢谢 :) – alexandernst