Driver duplicate?

Greg KH greg at kroah.com
Mon Mar 7 15:53:12 EST 2016


On Mon, Mar 07, 2016 at 03:37:24PM -0500, Kenneth Adam Miller wrote:
> 
> 
> On Mon, Mar 7, 2016 at 3:29 PM, Greg KH <greg at kroah.com> wrote:
> 
>     On Mon, Mar 07, 2016 at 03:21:44PM -0500, Kenneth Adam Miller wrote:
>     >
>     >
>     > On Mon, Mar 7, 2016 at 3:17 PM, Greg KH <greg at kroah.com> wrote:
>     >
>     >     On Mon, Mar 07, 2016 at 03:00:50PM -0500, Kenneth Adam Miller wrote:
>     >     > I have a driver that manages three sets of identical data
>     structures that
>     >     > differ only in address values. Currently, I pray that the device
>     file to
>     >     which
>     >     > I have callbacks mapped for the driver gets called sequentially,
>     because
>     >     there
>     >     > are pairs of mmap's that need to be made. I know that this isn't
>     the most
>     >     ideal
>     >     > way to do it, so I'm searching for a better way rather than to swap
>     out
>     >     the
>     >     > values on each method call. 
>     >     >
>     >     > There are several things I am aware of but for each one I have
>     questions:
>     >     > 1) there are kernel module parameters
>     >     > If I use kernel module parameters, I need to be able to insert the
>     kernel
>     >     > module three times in order to have each one have a distinct set of
>     >     global
>     >     > memory and mapped callbacks to distinct files. Can that be done?
>     Second,
>     >     I will
>     >     > need to compile the driver statically later. How can I pass those
>     >     parameters
>     >     > that would otherwise be on the command line in statically?
>     >
>     >     Never use kernel module parameters for a driver, nor for any other
>     >     kernel module you create.  They are global and don't work for
>     >     device-specific issues.
>     >
>     >     > 2) I can compile the driver in three times with a compile time
>     flag. This
>     >     is
>     >     > the simplest and easiest, but it requires some buildroot and
>     makefile foo
>     >     that
>     >     > I think is a dirty hack.
>     >
>     >     It's also never accepted, don't do that.
>     >
>     >     > 3) I could have the init function create three separate files,
>     since it
>     >     is on
>     >     > init that I discover what my values are. But then I have to also
>     >     associate
>     >     > identical functions that reference global variables in the kernel
>     object.
>     >     > Duplicating the code would be worse that compiling the same code
>     three
>     >     times
>     >     > with a kernel parameter, even though that would help me solve my
>     distinct
>     >     > globals problem. So how could I parameterisze a char device with
>     data
>     >     specific
>     >     > to the instance?
>     >
>     >     open() gives you the hook to do so, please just do that.  There's a
>     >     whole kernel tree full of examples of how to do this, take a look at
>     >     existing code please.
>     >
>     >
>     > After I had the idea in the second email, I think that using the kernel
>     api to
>     > distinguish which char device a callback maps to in order to utilize the
>     > corresponding data is the best way.
>     >
>     > If I could do something along the lines of retrieving the file name, as
>     in a
>     > char *,
> 
>     There is no such "thing" in the kernel (think of symlinks, or different
>     names for the same major:minor pair).
>    
>     > from the file * that is passed in with the callback, or distinguish any
>     > one of these:
>     >
>     > static dev_t LSKSMM_dev;
>     > static struct cdev LSKSMM_cdev;
>     > static struct class *LSKSMM_class;
>     > static struct device *LSKSMM_device;
> 
>     Those are all different things, none of them get passed into open().
> 
>     I don't think you have thought this through very far, where is your
>     source code to take a look at it?
>    
>     > which are also created on module init, it would really make things
>     convenient
>     > and easy. I'm currently digging around in the kernel headers, but I think
>     > probably somebody somewhere knows what I'm looking for. Some unique field
>     that
>     > I can retain on init that I can get back in my mmap/ioctl call to
>     recognize
>     > what data to use.
> 
>     Again, it's all provided directly to you in your open() call, what's
>     wrong with that?
> 
> 
> Currently, my kernel driver is opened twice and mmap'd twice by each process.

Again, any pointers to your source code?

> I have three processes, but I have to initialize them on startup with
> a startup script.

What does that have to do with the kernel code?

> So they come up as daemons, racing, which is a problem. I know that on
> init I can create three entries in /dev/, distinguished by a number or
> something that makes the device unique.

The kernel creates the /dev/ entries, don't do it from userspace, if you
expect things to work properly.

> When a mmap call hits is when I need to know what specific file that
> the mmap corresponds to.

Again, open() is giving you this, why do you keep saying it isn't?

And again, there are at least 3 different ways of determining this at
open() time (5 total I think, last time I looked), each way depends on
your driver structure and how your code needs to work, so I can't just
say "do it this way", sorry.

> I have to identify it associatively by name or by the identifiers that
> the kernel consumes for it's internal class and/or device entry.

Why?

> I don't know that I could do that with what I'm given in open, because
> while I'm sure that provides some information, it doesn't provide the
> the information when I need it.

All of the char drivers in the kernel kind of refute that excuse :)

> I don't have anything in my open callback except a printk.

Then fix that!

> My mmap does all the work, and has to distinguish the right private
> item to use with what device file.

Again, set that in your open() callback, that's what it is there for!

there is a whole kernel tree full of examples of how to do this, please
use them for insight.

thanks,

greg k-h



More information about the Kernelnewbies mailing list