Debian

在 4.9.82-ti-r102 debian 9.3 中寫入字元設備文件時核心拋出錯誤

  • February 28, 2020

/dev成功地在文件夾下創建了設備文件,但是寫入該設備文件會使核心拋出以下錯誤消息。

Message from syslogd@beaglebone at Feb 26 15:40:10 ... kernel:[10090.943733] Internal error: : 1b [#3] PREEMPT SMP ARM

Message from syslogd@beaglebone at Feb 26 15:40:10 ... kernel:[10091.049020] Process echo (pid: 3728, stack limit = 0xdc40a218)

Message from syslogd@beaglebone at Feb 26 15:40:10 ... kernel:[10091.054880] Stack: (0xdc40be60 to 0xdc40c000)

Message from syslogd@beaglebone at Feb 26 15:40:10 ... kernel:[10091.059267] be60: c15491c6 00000022 dc5cb14c bf30430c dc40bedc dc40be88 c075312c c074fe5c

Message from syslogd@beaglebone at Feb 26 15:40:10 ... kernel:[10091.067488] be80: c0753018 ffffff04 ffff0a00 c140414c c0d407c8 bf30430c c140414c 40cfbcf3

Message from syslogd@beaglebone at Feb 26 15:40:10 ... kernel:[10091.075709] bea0: 00852878 ffffff04 ffff0a00 00040952 c01a7404 c140414c 00852878 00852878

Segmentation fault

我非常了解 Linux 設備驅動程序

誰能幫我解決這個問題??

我附上了我用於字元文件寫入的程式碼片段

#include<linux/kernel.h>
#include<linux/init.h>
#include<linux/module.h>
#include<linux/fs.h>
#include<linux/uaccess.h>
#include<linux/device.h>


MODULE_AUTHOR("RUCHA");
MODULE_DESCRIPTION("Character Driver First test");
MODULE_LICENSE("GPL");
MODULE_VERSION("0.0.1");


static int MajorNum;
static struct class* RetValOfClassRegistration = NULL;
static struct device*  RetVal = NULL;
static char message[1024];
static int openDev(struct inode * , struct file *);
static int closeDev(struct inode * , struct file *);
static ssize_t readDev(struct file *, char *, size_t, loff_t *);
static ssize_t writeDev(struct file *, const char *, size_t, loff_t *);

static struct file_operations FileOps = {

   .owner = THIS_MODULE,
   .open = openDev,
   .read = readDev,
   .write = writeDev,
   .release = closeDev,

};

static int registerCharDev(void){

   return register_chrdev(0,"MyDev",&FileOps);
}

static int __init Loaded(void){

   // registering device

   MajorNum = registerCharDev();

   if(MajorNum < 0){
       printk("Can not register device\n");
       return -1;
   }

   printk("Driver Loaded with %d \n",MajorNum);


   // registering device class

   RetValOfClassRegistration = class_create(THIS_MODULE,"MyCharacterDriver");

   if(RetValOfClassRegistration < 0){

       printk("can not register class for driver number : %d\n",MajorNum);
       return 0;
   }


   // register the driver

   RetVal = device_create(RetValOfClassRegistration,NULL,MKDEV(MajorNum,0),NULL,"MyDev");


   return 0;

}


static void __exit Removed(void){
   device_destroy(RetValOfClassRegistration,MKDEV(MajorNum,0));
   class_unregister(RetValOfClassRegistration);
   class_destroy(RetValOfClassRegistration);
   unregister_chrdev(MajorNum,"MyDev");
   printk("Driver Removed\n");
}


module_init(Loaded);
module_exit(Removed);


static int openDev(struct inode *inodep , struct file *filep){

   printk("Device is now open to read write operations\n");
   return 0;
}


static int closeDev(struct inode *inodep , struct file *filep){

   printk("Device Closed\n");
   return 0;
}

static ssize_t readDev(struct file *filep, char *c, size_t v, loff_t *lp){

   printk("Read From the device\n");
   return 0;
}

static ssize_t writeDev(struct file *file, const char __user *buf, size_t len, loff_t *offset)
{
   sprintf(message, "%s(%zu letters)", buf, len);
   return 0;
}

我給出的使用者輸入是通過 echo 命令

迴聲'1’ > /dev/MyDev

請幫助我解決這個問題!

正如我所說…問題出在您的 char 驅動程序的write功能上。更具體地說,您正在直接從使用者空間訪問緩衝區。你不應該這樣做 - 核心有一個特定的 API。例如,請參閱有關該主題的StackOverflow 文章

對於您的特定情況,您應該刪除sprintf並使用copy_from_user將數據從使用者空間緩衝區復製到驅動程序的緩衝區中。這樣的事情解決了我的 beaglebone black board 上的問題:

static ssize_t writeDev(struct file *file, const char __user *buf, size_t len, loff_t *offset)
{
   printk("Write to device buf: 0x%p: len = %d, offset = %lld\n", buf, len, *offset);

   if (copy_from_user(message, buf, len)) {
       printk("Unable to read buffer from user\n");
       return -EFAULT;
   }   

   return len;
}

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