字符驱动设备查找失败

内核编译和嵌入式产品的设计与开发
回复
maple_169324
帖子: 11
注册时间: 2018-12-29 14:13
系统: ubuntu

字符驱动设备查找失败

#1

帖子 maple_169324 » 2020-12-02 15:58

sudo insmod chr_dev_mutex.ko
[16559.934862] devno=242221056
[16559.934864] globalmem init success

设备中能找到devno=231的设备
test@test:~/Linux_driver/.vscode/CH5$ cat /proc/devices
Character devices:
1 mem
4 /dev/vc/0
4 tty
4 ttyS
5 /dev/tty
5 /dev/console
5 /dev/ptmx
5 ttyprintk
6 lp
7 vcs
10 misc
13 input
21 sg
29 fb
89 i2c
99 ppdev
108 ppp
116 alsa
128 ptm
136 pts
180 usb
189 usb_device
204 ttyMAX
226 drm
231 globalmem_tmp
244 aux
245 hidraw

sudo mknod -m 766 /dev/globalmem_tmp c 231 0 新建一个设备

ls -al /dev | grep global
crwxrw-rw- 1 root root 231, 0 12月 2 15:43 globalmem_tmp

输入的时候提示找不到这个设备是什么原因呢
sudo echo "abc" > /dev/globalmem_tmp
bash: /dev/globalmem_tmp: No such device or address

代码如下

代码: 全选

#include <linux/module.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/delay.h>
#include <linux/wait.h>
#include <linux/sched/signal.h>


#define GLOBALMEM_SIZE             0x100
#define MEM_CLEAR                  0x1
#define GLOBALMEM_MAJOR            231

static int globalmem_major=GLOBALMEM_MAJOR;

module_param(globalmem_major,int,S_IRUGO);

struct globalmem_dev{
    struct cdev cdev;
    unsigned int current_len;
    unsigned char mem[GLOBALMEM_SIZE];
    struct mutex mutex;
    wait_queue_head_t r_wait;
    wait_queue_head_t w_wait;
};

struct globalmem_dev *globalmem_devp;



static ssize_t globalmem_read_queue(struct file *filp,char __user *buf,size_t size,loff_t *ppos)
{
    int ret;
    struct globalmem_dev *dev=filp->private_data;
    DECLARE_WAITQUEUE(wait,current);
    mutex_lock(&dev->mutex);
    add_wait_queue(&dev->r_wait,&wait);
    while(dev->current_len == 0){
        if(filp->f_flags & O_NONBLOCK){
            printk(KERN_INFO "NONBLOCK_DEVICE\n");
            ret=-EAGAIN;
            goto out;
        }
        __set_current_state(TASK_INTERRUPTIBLE);
        mutex_unlock(&dev->mutex);
        schedule();
        if(signal_pending(current)){
            ret=-ERESTARTSYS;
            goto out2;
        }
        mutex_lock(&dev->mutex);
    }
    if(size > dev->current_len)
        size=dev->current_len;
    if(copy_to_user(buf,dev->mem,size)){
        printk("copy_to_user_fail\n");
        ret=-EFAULT;
        goto out;
    }
    else
    {
        memcpy(dev->mem,dev->mem+size,dev->current_len-size);
        dev->current_len-=size;
        printk(KERN_INFO "read %d bytes,current_len:%d\n",size,dev->current_len);
        wake_up_interruptible(&dev->w_wait);
        ret=size;
    }
    out:
        mutex_unlock(&dev->mutex);
    out2:
        remove_wait_queue(&dev->w_wait,&wait);
        set_current_state(TASK_RUNNING);

    return ret;
}



static ssize_t globalmem_write(struct file *filp,const char __user *buf,size_t size,loff_t *ppos)
{
    unsigned long p=*ppos;
    unsigned int count=size;
    int ret=0;
    struct globalmem_dev *dev=filp->private_data;
    DECLARE_WAITQUEUE(wait,current);
    mutex_lock(&dev->mutex);
    add_wait_queue(&dev->w_wait,&wait);
    while(dev->current_len == GLOBALMEM_SIZE)
    {
        if(filp->f_flags & O_NONBLOCK){
            printk(KERN_INFO "NONBLOCK_DEVICE\n");
            ret = -1;
            goto out;
        }
        __set_current_state(TASK_INTERRUPTIBLE);
        mutex_unlock(&dev->mutex);
        schedule();
        if(signal_pending(current)){
            ret =-1;
            goto out2;
        }
        mutex_lock(&dev->mutex);
    }
    if(copy_from_user(dev->mem+p,buf,count)){
        ret=-1;
    }
    else
    {
        dev->current_len+=count;
        printk(KERN_INFO "written %d bytes,current_len:%d\n",count,dev->current_len);
        wake_up_interruptible(&dev->r_wait);
    }
out:
    mutex_unlock(&dev->mutex);
out2:
    remove_wait_queue(&dev->w_wait,&wait);
    set_current_state(TASK_RUNNING);
    return ret;
}


static loff_t globalmem_llseek(struct file *filp,loff_t offset,int orig)
{
    loff_t ret=0;
    switch(orig){
        case 0:
            if(offset < 0)
            {
                ret =-1;
                break;
            }
            if((unsigned int)offset > GLOBALMEM_SIZE){
                ret = -1;
                break;
            }
        case 1:
            if((filp->f_pos+offset) < 0){
                ret =-1;
                break;
            }
            filp->f_pos+=offset;
            ret=filp->f_pos;
            break;
        default:
            ret =-1;
            break;
    }
    return ret;
}


static long globalmem_ioctl(struct file *filp,unsigned int cmd,unsigned long arg)
{
    struct globalmem_dev *dev=filp->private_data;
    switch(cmd){
        case MEM_CLEAR:
            mutex_lock(&dev->mutex);
            memset(dev->mem,0,GLOBALMEM_SIZE);
            printk(KERN_INFO "globalmem is set to zero\n");
            mutex_unlock(&dev->mutex);
            break;
        default:
            return -1;
    }
}


static int globalmem_open(struct inode *inode,struct file *filp)
{
    filp->private_data=globalmem_devp;
    return 0;
}

static int globalmem_release(struct inode *inode,struct file *filp)
{
    return 0;
}


static const struct file_operations globalmem_fops={
    .owner=THIS_MODULE,
    .llseek=globalmem_llseek,
    .read=globalmem_read_queue,
    .write=globalmem_write,
    .unlocked_ioctl=globalmem_ioctl,
    .open=globalmem_open,
    .release=globalmem_release,
};



static void globalmem_setup_cdev(struct globalmem_dev *dev,int index)
{
    int err,devno=MKDEV(globalmem_major,index);
    dev->cdev.owner=THIS_MODULE;
    err=cdev_add(&dev->cdev,devno,1);
    if(err)
        printk(KERN_NOTICE "Error %d adding globalmem%d",err,index);
}


static int __init globalmem_init(void)
{
    int ret;
    dev_t devno=MKDEV(globalmem_major,0);
    printk("devno=%d\n",devno);
    if(globalmem_major)
        ret=register_chrdev_region(devno,1,"globalmem_tmp");
    else{
        ret=alloc_chrdev_region(&devno,0,1,"globalmem_tmp");
        globalmem_major=MAJOR(devno);
    }
    if(ret < 0)
        return ret;
    globalmem_devp=kzalloc(sizeof(struct globalmem_dev),GFP_KERNEL);
    if(!globalmem_devp){
        ret=-EFAULT;
        goto fail_malloc;
    }

    mutex_init(&globalmem_devp->mutex);
    globalmem_setup_cdev(globalmem_devp,0);
    printk("globalmem init success\n");
    init_waitqueue_head(&globalmem_devp->r_wait);
    init_waitqueue_head(&globalmem_devp->w_wait);
    return 0;
    fail_malloc:
        unregister_chrdev_region(devno,1);
        return ret;
}


module_init(globalmem_init);

static void __exit globalmem_exit(void)
{
    cdev_del(&globalmem_devp->cdev);
    kfree(globalmem_devp);
    unregister_chrdev_region(MKDEV(globalmem_major,0),1);
}

module_exit(globalmem_exit);

MODULE_AUTHOR("MAPLE");
MODULE_LICENSE("GPL V2");

头像
astolia
论坛版主
帖子: 6453
注册时间: 2008-09-18 13:11

Re: 字符驱动设备查找失败

#2

帖子 astolia » 2020-12-04 11:09

你定义的globalmem_fops根本没有和你注册的设备绑定啊,自己在初始化时调用cdev_init去。
话说回来你的模块在卸载时在cdev_del这步直接出错,dmesg的信息都提示你了
kobject: 'globalmem_tmp' (0000000049e69422): is not initialized, yet kobject_put() is being called.
回复