为什么寄存器字符设备不可见?

时间:2014-04-15 08:37:24

标签: kernel kernel-module

我通过查看示例制作了简单的字符驱动程序。但是,我没有看到/ dev / simple中的驱动程序简单。为什么不在那里创建?我也没有看到任何错误问题。我错过了什么,有什么问题吗?

#include <linux/init.h>
#include <linux/module.h> /** needed by all modules **/
#include <linux/kernel.h>  /** This is for KERN_ALERT **/
#include <linux/fs.h>
#include <linux/cdev.h>

/** for putuser **/
 #include <asm/uaccess.h>

MODULE_LICENSE("SJ BSD/GPL");


static struct cdev SimpleDevs[2];

static int simple_major = 0;


static ssize_t sj_read(struct file *filp,
   char *buffer,    /* The buffer to fill with data */
   size_t length,   /* The length of the buffer     */
   loff_t *offset);

static int sj_open(struct inode *inode, struct file *file);   


static struct file_operations fops = {
  .read = sj_read,
  //.write = sj_write,
  .open = sj_open,
  //.release = sj_release
};

static ssize_t sj_read(struct file *filp,
   char *buffer,    /* The buffer to fill with data */
   size_t length,   /* The length of the buffer     */
   loff_t *offset)  /* Our offset in the file       */
{

     char msg[1024] = "Hello SJ_read";
     copy_to_user( buffer, msg, sizeof(msg) );

      return sizeof(msg);

}

static void simple_setup_cdev(struct cdev *dev, int minor,
                 struct file_operations *fops)
{
        int err, devno = MKDEV(simple_major, minor);

         dev = cdev_alloc();

         cdev_init(dev, fops);
         dev->owner = THIS_MODULE;
         dev->ops = fops;
         err = cdev_add (dev, devno, 1);
         /* Fail gracefully if need be */
         if (err)
                 printk (KERN_NOTICE "Error %d adding simple%d", err, minor);
 }

static int sjDevInit(void)
{

    int result;
    dev_t dev; 

    printk("Device Init now..");


    /** int alloc_chrdev_region(dev_t *dev, unsigned int firstminor,unsigned int count, char *name);  **/
    /** dev -> The dev_t variable type,which will get the major number that the kernel allocates.  **/
    /**The same name will appear in /proc/devices.  **/
    result = alloc_chrdev_region(&dev, 0, 1, "simple");
    if( result < 0 )
    {
      printk("Error in allocating device");
      return -1;    
    }
    // printk("simple_major ..");
     simple_major = MAJOR(dev);
     printk("simple_major number is %d ..\r\n",simple_major );

    /* Now set up two cdevs. */

    simple_setup_cdev(SimpleDevs, 0, &fops);
    simple_setup_cdev(SimpleDevs + 1, 1, &fops);

    return 0;

}


static void sjDevRel(void)
{
    printk("Releasing Simple Devs\r\n");
    cdev_del(SimpleDevs);

}

static int sj_open(struct inode *inode, struct file *file)
{

   printk("Kernel..Sj_open ..I am opened\r\n");

   return 0;
}

module_init(sjDevInit);
module_exit(sjDevRel);

1 个答案:

答案 0 :(得分:1)

节点设备可以在收到mknod消息时手动创建(通过直接调用udevd)或uevent守护程序。该消息由“操作”字段(ADDREMOVE等)和一组键{/值对组成,udevd可以查看以决定调用哪个规则。

要发出事件,您需要获取kobject((struct cdev *)->kobj)的句柄。完全创建设备后,您需要执行以下操作:

err = cdev_add (dev, devno, 1);
/* Fail gracefully if need be */
if (err)
    printk (KERN_NOTICE "Error %d adding simple%d", err, minor);
kobject_uevent(&dev->kobj, KOBJ_ADD);

在移除设备之前,您需要执行相反的操作:

kobject_uevent(&SimpleDevs[0]->kobj, KOBJ_REMOVE);
printk("Releasing Simple Devs\r\n");
cdev_del(SimpleDevs[0]);

(顺便说一句,你的代码有一个主要的指针处理错误,涉及你SimpleDevs变量的定义和用法,你应该对其进行整理和修复。

此时您可以使用udevadm monitor命令进行实验,看看您是否从驱动程序获取消息并使用任何udev教程编写适当的规则(例如:https://wiki.debian.org/udev

如果您想为您的uevent消息添加更多信息,可以尝试使用更详细的kobject_uevent_env() API。这通常看起来像这样:

char event[] = "DISK_RO=1";
char *envp[] = { event, NULL };

if (!ro)
    event[8] = '0';
kobject_uevent_env(&disk_to_dev(gd)->kobj, KOBJ_CHANGE, envp);

http://code.metager.de/source/xref/linux/stable/block/genhd.c#1320

如果你想要更高级的消息,通常的方法是保留一个适当大小的固定内存块,并在将其传递给uevent之前用snprintf填充它。