我正在学习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;你好"
谢谢
答案 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()
等函数来访问用户空间缓冲区。