Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

I am trying to build a simple kernel module. Following are the contents of file involved in it:

module.c:

    #include <linux/init.h>
    #include <linux/fs.h>
    #include <linux/device.h>
    #include <linux/kernel.h>
    #include "header.h"






    static int device_open(struct inode *inode, struct file *file)
    {
    printk("\n Open \n");
    return 0;
    }

    static int device_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long args)
    {
    switch(cmd)
    {
    case IOCTL_CMD:
    printk(KERN_ALERT "\n %s \n", (char *)args);
    break;
    }
    return 0;
    }


    static int device_release(struct inode *inode, struct file *file)
    {
    printk("\n Release \n");
    return 0;
    }

    static struct class *my_class;

    static struct file_operations fops={
    .open = device_open,
    .release = device_release,
    .compat_ioctl = device_ioctl
    };

    static int hello_init(void)
    {
    major_no = register_chrdev(0, DEVICE_NAME, &fops);
    printk("\n Major_no : %d", major_no);

    my_class = class_create(THIS_MODULE, DEVICE_NAME);
    device_create(my_class, NULL, MKDEV(major_no,0), NULL, DEVICE_NAME);
    printk("\n Device Initialized in kernel ....!!!");
    return 0;
    }




    static void hello_exit(void)
    {
    printk("\n Device is Released or closed \n");
    device_destroy(my_class,MKDEV(major_no,0));
    class_unregister(my_class);
    class_destroy(my_class);
    unregister_chrdev(major_no, DEVICE_NAME);
    printk("\n===============================================================\n");
    }



    module_init(hello_init);
    module_exit(hello_exit);

    MODULE_LICENSE("GPL");

appln.c

    #include <stdio.h>
    #include <fcntl.h>
    #include <string.h>

    #include "header.h"

    int main()
    {
    int fd;
    char * msg = "yahoooo";
    fd = open(DEVICE_PATH, O_RDWR);
    ioctl(fd, IOCTL_CMD, msg);
    printf("ioctl executed\n");
    close(fd);
    return 0;
    }

header.h:

    #include <linux/ioctl.h>
    #include <linux/kdev_t.h> /* for MKDEV */

    #define DEVICE_NAME "my_dev"
    #define DEVICE_PATH "/dev/my_dev"
    #define WRITE 0
    static int major_no;
    #define MAGIC_NO '4'
    /* 
     * Set the message of the device driver 
     */
    #define IOCTL_CMD _IOR(MAGIC_NO, 0, char *)

My module loads perfectly(I can see the mesg in hello_init() function). But when i run the appln.c program, even when it makes the ioctl() call, I see no result of it. Can someone tell why is the module ignoring my ioctl call.

Thanks,

share|improve this question

1 Answer 1

up vote 2 down vote accepted

A few things:

  • You want to use "unlocked_ioctl" not "compat_ioctl".
  • The function interface for "device_ioctl" is wrong (see include/linux/fs.h), it should be:

        long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
    
  • The appln.c doesn't check error codes (open, ioctl).

After fixing that, the code will work fine.

share|improve this answer
    
Kees Cook: Thanks, One more thing what is the difference b/w unlocked_ioctl and device_ioctl. Is there any updated source of reference, for module development, that lists all such changes with kernel code. –  gkt Jul 25 '11 at 18:12

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.