Files

貓:寫錯誤:無效的參數

  • March 28, 2019

使用寫入自定義字元設備

貓 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);

所以在這裡我們可以看到我什至使用了一個 device_write 函式並將其在 fops 結構中分配給 .write。那麼它不應該接受寫入命令並在日誌中列印該語句嗎?

在核心中,每個驅動程序都為可以對文件執行的各種操作提供了一系列方法:打開、關閉、讀取、寫入、查找、ioctl 等。這些方法儲存在struct file_operations. 對於設備,方法由註冊該特定設備(即塊/字元、主設備號和次設備號的特定組合)的驅動程序提供。

驅動程序可能只實現一些方法;提供預設值。預設值通常不執行任何操作並返回成功(如果對該方法不執行任何操作是明智的)或 EINVAL(如果沒有合理的預設值並且缺少方法意味著不支持該功能)。

“Write error: Invalid argument”表示write驅動的方法返回EINVAL。最可能的解釋是這個驅動程序根本沒有write方法。驅動程序不支持某些操作是相當正常的,例如,一些驅動程序只支持 ioctl 而不支持讀/寫,一些驅動程序本質上是單向的(例如輸入設備),只支持讀而不支持寫,反之亦然。

“無效參數”與權限無關,這是設備能夠做到的。如果您沒有寫權限,則會收到權限錯誤,但您確實有權與驅動程序交談。只是你要求司機做的事情是它沒有概念的。

引用自:https://unix.stackexchange.com/questions/319936