当前位置:  技术问答>linux和unix

insmod命令加载字符设备驱动成功后,在/proc/devices文件内却并没有该驱动名字和主设备号信息

    来源: 互联网  发布时间:2017-04-10

    本文导语:  本帖最后由 gongmin856 于 2013-05-05 20:09:31 编辑 insmod命令加载globalfifo字符设备驱动成功后,我从globalfifo_init函数打出的调试信息显示,系统分配给该设备的主设备号为253,次设备号为0,但在/proc/devices文件内却并没有该...

本帖最后由 gongmin856 于 2013-05-05 20:09:31 编辑
insmod命令加载globalfifo字符设备驱动成功后,我从globalfifo_init函数打出的调试信息显示,系统分配给该设备的主设备号为253,次设备号为0,但在/proc/devices文件内却并没有该设备名字和主设备号信息.

以下是该设备驱动代码,请大家帮帮忙,看看是怎么回事啊?提前谢谢了!

#include
#include
#include 
#include
#include
#include

#define GLOBALFIFO_SIZE    (0x1000)   /*全家内存最大值4KB*/
#define MEM_CLEAR     (0x1)       /*清零全局内存*/
#define GLOBALFIFO_MAJOR (0)       /*预设的GloabalMem的主设备号*/

static int globalfifo_major = GLOBALFIFO_MAJOR;

/*global_mem设备结构体*/
struct globalfifo_dev{
struct cdev cdev; /*cdev结构体*/
unsigned int current_len;/*fifo有效数据长度*/
unsigned char mem[GLOBALFIFO_SIZE]; /*全局内存*/
struct semaphore sem;/*并发控制用的信号量*/
wait_queue_head_t r_wait;/*阻塞读用的等待队列头*/
wait_queue_head_t w_wait;/*阻塞写用的等待队列头*/
};

struct globalfifo_dev *globalfifo_devp; /*设备结构体指针*/
 
int globalfifo_open(struct inode *inode, struct file *filp)
{
/*将设备结构体指针赋值给文件私有数据指针*/
     filp->private_data = globalfifo_devp;
     return 0;
}

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

static long globalfifo_ioctl(struct file *filep,unsigned int cmd, unsigned long arg)
{
struct globalfifo_dev *dev =  filep->private_data;

switch(cmd) {
case MEM_CLEAR:
memset(dev->mem, 0x0, sizeof(dev->mem));
printk(KERN_INFO "globalmem is clearn");
break;

default:
return -EINVAL;
}

return 0;
}

static ssize_t globalfifo_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
{
unsigned long p = *ppos;
unsigned int count = size;
int ret = 0;
struct globalfifo_dev *dev =  filp->private_data;     
DECLARE_WAITQUEUE(wait, current);

down(&(dev->sem)); /*持有信号量*/

add_wait_queue(&dev->r_wait, &wait);

while(dev->current_len == 0)
{
if(filp->f_flags & O_NONBLOCK)
{
ret = -EAGAIN;
goto out;
}

__set_current_state(TASK_INTERRUPTIBLE); /*改变进程状态为睡眠*/

up(&dev->sem);

schedule();/*调度其他进程运行*/

if(signal_pending(current))
{
ret = -ERESTARTSYS;
goto out2;
}

down(&dev->sem);
}

      if(p >= GLOBALFIFO_SIZE)
return 0;
      if(count > (GLOBALFIFO_SIZE -p))
   count = GLOBALFIFO_SIZE -p;

/*kernel space --> user's space*/
if(copy_to_user(buf, (void *)(dev->mem+p), count)) {
ret = -EFAULT;
goto out;
} else {
//*ppos += count;
memcpy(dev->mem, dev->mem + count, dev->current_len- count);
ret = count;
printk(KERN_INFO "read %u bytes from %lun", count, p);

wake_up_interruptible(&dev->w_wait); /*唤醒写等待队列*/
}

out:up(&dev->sem);
out2:remove_wait_queue(&dev->r_wait, &wait);/*移除等待队列*/
set_current_state(TASK_RUNNING);

return ret;
}

static ssize_t globalfifo_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 globalfifo_dev *dev =  filp->private_data;     

DECLARE_WAITQUEUE(wait, current);

down(&(dev->sem)); /*持有信号量*/

add_wait_queue(&dev->w_wait, &wait);

while(dev->current_len == GLOBALFIFO_SIZE)
{
if(filp->f_flags & O_NONBLOCK)
{
ret = -EAGAIN;
goto out;
}

__set_current_state(TASK_INTERRUPTIBLE); /*改变进程状态为睡眠*/

up(&dev->sem);

schedule();/*调度其他进程运行*/

if(signal_pending(current))
{
ret = -ERESTARTSYS;
goto out2;
}

down(&dev->sem);
}

      if(p >= GLOBALFIFO_SIZE)
return 0;
      if(count > (GLOBALFIFO_SIZE -p))
   count = GLOBALFIFO_SIZE -p;

/* user's space --> kernel space */
if(copy_from_user(dev->mem + dev->current_len, buf, count)) {
ret = -EFAULT;
goto out;
} else {
//*ppos += count;
ret = count;
printk(KERN_INFO "write %u bytes,cur_len:%dn", count, dev->current_len);

wake_up_interruptible(&dev->r_wait);
}

out:up(&dev->sem);
out2:remove_wait_queue(&dev->w_wait, &wait);/*移除等待队列*/
set_current_state(TASK_RUNNING);

return ret;
}

static loff_t globalfifo_lllseek(struct file *filp, loff_t offset, int orig)
{
loff_t  ret = 0;
switch(orig) {
case 0:/*相对文件开始位置偏移*/
if ((offset  GLOBALFIFO_SIZE)) {
ret = -EINVAL;
break;
}

filp->f_pos = (unsigned int)offset;
ret = filp->f_pos;
break;
case 1: /*根据文件当前位置偏移*/
if ((filp->f_pos + offset) > GLOBALFIFO_SIZE) {
ret = -EINVAL;
break;
}

filp->f_pos += (unsigned int)offset;
ret = filp->f_pos;
break;
default:
ret = -EINVAL;
break;
}

return ret;
}

static const struct file_operations globalfifo_filp = {
.owner = THIS_MODULE,
.llseek = globalfifo_lllseek,
.read = globalfifo_read,
.write = globalfifo_write,
.unlocked_ioctl = globalfifo_ioctl,
.open = globalfifo_open,
.release = globalfifo_release,
};

static void globalfifo_setup_cdev(struct globalfifo_dev *dev, int index)
{
int err;
int devno = MKDEV(globalfifo_major, index);

cdev_init(&dev->cdev, &globalfifo_filp);

dev->cdev.owner = THIS_MODULE;
err = cdev_add(&dev->cdev, devno, 1);

if (err)
printk(KERN_NOTICE "Error %d adding globalmem %dn", err, index);
}

int globalfifo_init(void)
{
int result;
dev_t devno = MKDEV(globalfifo_major, 0);

/*申请设备号*/
if (globalfifo_major)
result = register_chrdev_region(devno, 1, "globalfifo");
else {/*动态申请设备号*/
result = alloc_chrdev_region(&devno, 0, 1, "globalfifo");

if(result sem), 1);/*初始化信号量*/

init_waitqueue_head(&(globalfifo_devp->w_wait));/*初始化写等待队列头*/
init_waitqueue_head(&(globalfifo_devp->r_wait));/*初始化读等待队列头*/

fail_malloc:
unregister_chrdev_region(devno, 1);
return result;

}

void globalfifo_exit(void)
{
cdev_del(&globalfifo_devp->cdev);/*注销cdev*/
kfree(globalfifo_devp);

unregister_chrdev_region(MKDEV(globalfifo_major, 0), 1);
}

module_init(globalfifo_init);
module_exit(globalfifo_exit);
module_param(globalfifo_major, int , S_IRUGO);

MODULE_AUTHOR("Barry song");
MODULE_LICENSE("Dual BSD/GPL");

|
两个问题,1, 动态申请设备号的时候没有更新globalfifo_major的值

fail_malloc:
 unregister_chrdev_region(devno, 1);
 return result;
成功的话,在这之前需要return,不然申请后立刻退出,
 return 0;加这句就可以了
fail_malloc:
 unregister_chrdev_region(devno, 1);
 return result;

    
 
 

您可能感兴趣的文章:

  • insmod 加载驱动模块后,重启后驱动为什么没有了
  • Linux串口驱动insmod后无效
  • 驱动编译insmod问题,100分相送,在线等待,有效马上结贴
  • s3c2410 linux操作系统 insmod 驱动错误 内存耗尽
  • insmod 后的驱动程序 怎么访问? dev目录里面没有啊
  • 我下载了一个驱动,在2.4内核编译后用insmod加载说内核版本不一样?
  • 有人在学习网卡驱动吗?不知道网卡驱动的测试程序怎么写。是不是insmod之后就直接ping试一下??
  • 请问,insmod 是不是把驱动和lib下的库进行连接?
  • linux字符驱动insmod出现错误
  • insmod: : unknown symbol in module不能加载驱动问题
  • 设备驱动编译无措,加载insmod不上(无错误提示)
  • watchdog驱动insmod: No such device
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 升级linux到2.6.11后insmod模块都出现insmod invalid format??
  • insmod加载模块问题
  • 请高手帮忙解释一下,insmod ./$module.ko || exit 1中的“||”是什么意思啊,多谢!
  • 运行insmod ip_tables后,reboot后又无效了?
  • insmod加载模块问题.
  • 如何在程序中执行 insmod mydriver.ko命令?
  • insmod是否每次开机都要运行
  • insmod 加载sis650_dvr.o-4-02
  • insmod或modprobe具体怎么用啊
  • RH9.0 insmod命令在默认的shell中找不到?
  • 自己写的模块insmod后变成permanent了。。。。奇怪
  • 在开发板上insmod模块led.o出错。
  • insmod模块无显示,但rmmod模块有显示
  • insmod 加载驱动模块后,重启后驱动为什么没有了 iis7站长之家
  • insmod bridge.ko出错
  • [急] insmod时,报错unresolved symbol!!
  • insmod scull.ko出错 Unknown symbol in module
  • insmod 安装内核模块的问题
  • 新手请教insmod -f ./$module.o $* || exit 1
  • 内核模块加载时insmod:error inserting 'XXX.ko':-136704000 Success


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,