Sak*_*thi 4 kernel devices files cat
使用写入自定义字符设备
猫 123 > /dev/chardev
给
猫:写错误:无效的参数
我已将权限更改为 666,甚至使用 sudo 进行了尝试。结果还是一样。也以类似的方式尝试回声
我使用 Arch linux 4.8。
编辑:驱动程序的代码
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
//Prototypes
static int __init init(void);
static void __exit cleanup(void);
static int device_open(struct inode *,struct file *);
static int device_release(struct inode *, struct file *);
static ssize_t device_read(struct file *, char *, size_t, loff_t *);
static ssize_t device_write(struct file *, const char *, size_t, loff_t *);
#define SUCCESS 0
#define DEVICE_NAME "chardev" /* Dev name as it appears in /proc/devices*/
#define BUF_LEN 80 /* Max length of the message from the device */
static int Major; //Major number of the devices
static int Device_Open = 0;
static char msg[BUF_LEN]; //Message given when asked
static char *msg_Ptr;
static struct file_operations fops = {
.read = device_read,
.write = device_write,
.open = device_open,
.release = device_release
};
static int __init init(){
Major = register_chrdev(0,DEVICE_NAME,&fops);
if(Major < 0){
printk(KERN_ALERT "Failure in registering the device. %d\n", Major);
return Major;
}
printk(KERN_INFO "%s registered with major %d \n",DEVICE_NAME,Major);
printk(KERN_INFO "create a device with 'mknod /dev/%s c %d 0'\n",DEVICE_NAME,Major);
printk(KERN_INFO "Try to cat and echo the file and shit man.\n");
return SUCCESS;
}
static void __exit cleanup(){
unregister_chrdev(Major, DEVICE_NAME);
printk(KERN_ALERT "Unregistered the device %s i guess? \n"DEVICE_NAME);
}
static int device_open(struct inode *inode,struct file *file){
static int counter = 0;
if(Device_Open)
return -EBUSY;
Device_Open++;
sprintf(msg, "I already told you %d times Hello world!\n", counter++);
msg_Ptr = msg;
try_module_get(THIS_MODULE);
return SUCCESS;
}
static int device_release(struct inode *inode,struct file *file){
Device_Open--;
module_put(THIS_MODULE);
return 0;
}
static ssize_t device_read(struct file *filp, char *buffer, size_t length, loff_t * offset){
int bytes_read = 0;
if(*msg_Ptr == 0)
return 0;
while(length && *msg_Ptr){
put_user(*(msg_Ptr++),buffer++);
length--;
bytes_read++;
}
return bytes_read;
}
static ssize_t device_write(struct file *filp,const char *buff, size_t len, loff_t *off){
printk(KERN_ALERT "You cannot write to this device.\n");
return -EINVAL;
}
module_init(init);
module_exit(cleanup);
Run Code Online (Sandbox Code Playgroud)
所以在这里我们可以看到我什至使用了一个 device_write 函数并将它在 fops 结构中分配给 .write。那么它不应该接受写入命令并在日志中打印该语句吗?
Gil*_*il' 11
在内核中,每个驱动程序都为可以对文件执行的各种操作提供了一系列方法:打开、关闭、读取、写入、查找、ioctl 等。这些方法存储在一个struct file_operations. 对于设备,方法由注册该特定设备的驱动程序提供(即块/字符、主编号和次要编号的特定组合)。
驱动程序可能只实现其中的一些方法;提供了默认值。默认值通常不执行任何操作并返回成功(如果对该方法不执行任何操作是明智的)或 EINVAL(如果没有合理的默认值并且缺少方法意味着不支持该功能)。
“写入错误:无效参数”表示write驱动程序的方法返回 EINVAL。最可能的解释是该驱动程序根本没有write方法。驱动程序不支持某些操作是很正常的,例如有些驱动程序只支持 ioctl 而不是读/写,有些驱动程序本质上是单向的(例如输入设备)并且只支持读而不支持写,反之亦然。
“无效参数”与权限无关,它是设备能够执行的操作。如果您没有写权限,您会收到权限错误,但您确实有权与驱动程序交谈。只是你要求司机做的事情是它没有概念的。