alexandernst
alexandernst

Reputation: 15109

Sending data from LKM to userspace

I have a Linux Kernel Module that generates data and I'd like to send that data to a userspace application. What are the options and what pros/cons do they have?

The data could be, let's say, 100 structs of a few char[] and a few int[] per second.

Also, if possible (not mandatory), I'd like those structs to get to userland in the same order as they are generated in the LKM.

Upvotes: 1

Views: 919

Answers (2)

Daniel Santos
Daniel Santos

Reputation: 3295

Create a character driver and use the read function to return this. By far, the absolute best tutorial for this is in LDD3 (Linux Device Drivers, Third Edition) which, hey! you can download for free! So you fill out your struct file_operations and populate these fields:

static const struct file_operations my_fops = {
    .owner =    THIS_MODULE,
    .read =     my_read,
    .open =     my_open,
    .release =  my_release,
};

Pass that puppy to cdev_init(), etc. So that's where you spew your data (in my_read())

EDIT: Oh yeah, and I own the physical book of this and it's definitely one of my most worn from use, toting around, etc.

EDIT2: Ahh, so you want pros & cons now eh? :) I would say that the biggest pro of a character driver is that you don't have to get a syscall number from Torvolds. :) Well, then again, you don't have to do that if you aren't trying to distribute your patch. A character driver is very straight forward and easy to implement. You can also use an ioctl if you want the userland app to be able to request different data and have that data returned only upon request. Alternatively, you can have the userland app write a request and only receive data from your read function when it gets a request, but I'm presuming you just want a constant data spew. In that case, just have your read function write (to userland) everything it gets from whatever part of your module it comes from, as it gets it and in the order you want to send it.

One more thought, if you're dealing with very large amounts of data and are encountering bottlenecks, you may want to consider writing it to your user-space app via mmaped memory. However, I honestly don't have great expertise in that particular area.

Oh yeah, also keep in mind that your struct file_operations functions can sleep and maybe other parts of your module can't. just a note

Upvotes: 2

akp
akp

Reputation: 1823

You can try passing structure which will contain the buffer pointer & the size of the buffer. But the same structure should also be defined in both user-space application & inside your system-call's code in kernel.

     struct new_struct
        {
           void *p;  //set this pointer to your buffer...
           int size;
        };
        //from user-application...

        int main()
        {
           ....
           struct new_struct req_kernel;
           your_system_call_function(...,(void *)&req_kernel,...);
           // here u can get the data which is copied from kernel-space in req_kernel                      structure.
        }


........................................................................................


  //this is inside your kernel...
     your_system_call(...,char __user optval,...)
     {
            .....
            struct new_struct req;
           // fill the data in the resq structure. which will be access in user-space.
            if (copy_to_user(&req, optval, sizeof(req)))

            return -EFAULT;
            //now you have the address or pointer & size of the buffer
            //which you want in kernel with struct req...
    }

refer to http://people.ee.ethz.ch/~arkeller/linux/kernel_user_space_howto.html

Upvotes: 1

Related Questions