了解char驱动程序中的写文件操作

时间:2014-12-31 13:35:23

标签: linux-kernel linux-device-driver


我正在学习char驱动程序。但我并不理解char设备驱动程序的写操作。以下是我的写作操作

static ssize_t dev_write(struct file *fil,const char *buff,size_t len,loff_t *off)
{
    int count =0;
    int i =0;
    int flag=0;
    pr_info("user input string %s\n",buff);
    pr_info("user input string len %d\n",len);
    return len;
}

我的疑问是,如果我写入我的设备,如

echo "hello" > /dev/myDev

以下是dmesg的内容

[20596.975355] user input string hello
[20596.975355] 77b9e4
[20596.975355] insmod insmod
[20596.975355] n/zeitgeist-daemon
[20596.975355] atives
[20596.975355] 
[20596.975355] vars "${upargs[@]}"
[20596.975355]  cur cword words=();
[20596.975355]     local upargs=() upvars=() vcur vcword vprev vwords;
[20596.975355]     while getopts "c:i:n:p:w:" flag "$@"; do
[20596.975355]         case $flag in 
[20596.975355]             c)
[20596.975355]                 vcur=$OPTARG
[20596.975355]             ;;
[20596.975355]             i)
[20596.975355]                 vcword=$OPTARG
[20596.975355]             ;;
[20596.975355]             n)
[20596.975355]                 exclude=$OPTARG
[20596.975355]             ;;
[20596.975355]             p)
[20596.975355]                 vprev=$OPTARG
[20596.975355]             ;;
[20596.975355]             w)
[20596.975355]                 vwords=$OPTARG
[20596.975355]             ;;
[20596.975358] user input string len 6
[20596.975361] Device closed

所以我不明白里面发生了什么。可以解释一下发生了什么吗?
如何只访问用户输入的字符串,即#34;你好"
谢谢

2 个答案:

答案 0 :(得分:1)

当您在" / dev / myDev"上执行echo时文件,这在用户空间中调用write("/dev/myDev")系统调用。这转换为file_operations ops (struct file_operations *)->write调用在内核空间中调用函数dev_write()

现在看起来原始定义可能是错误的,因为它缺少__user,它指向用户空间应用程序缓冲区。它不建议直接打印或使用缓冲区的用户空间,因为这会弄乱一些东西并打印许多其他数据,可能是某些与某些程序的.text部分相关的页面。

相反,您应该使用创建内核缓冲区并使用copy_from_user()simple_write_to_buffer()复制内容,然后将缓冲区打印到syslog中。这个内核空间页面的原因始终固定在内存中,并且不会页面调出页面输出,而允许用户空间页面使用copy_{from,to}_user()和{{} {}进行内存页面调出。 {1}}首先验证指针页面,以确保从这些缓冲区读取时不会发生页面错误。

例如:     static ssize_t dev_write(struct file * fil,const char __ user * buff,size_t len,loff_t * off)

希望这有帮助。

答案 1 :(得分:1)

%s期望一个以零结尾的字符串,但write()的缓冲区只包含实际写入的字节数。

此外,由于程序使用了错误的指针,用户空间缓冲区可能会被换出或不存在,因此您必须始终使用get_user()copy_from_user()等函数来访问用户空间缓冲区。