Device file not appearing

Greg KH greg at kroah.com
Wed Mar 17 11:59:08 EDT 2021


On Wed, Mar 17, 2021 at 09:52:32AM -0600, Gregory Anders wrote:
> Hi all,
> 
> I'm writing a char device driver and am having trouble getting the file to
> appear under /dev.
> 
> This isn't my first rodeo: in fact, I've written a few other drivers in the
> past and they have all worked as expected. This driver is based on the
> source code of those other drivers, so I'm fairly confident I'm doing
> everything correctly. So I'm stumped and looking for help.
> 
> Here is what I have in my init function:
> 
>     #define DRIVER_NAME "foo"
> 
>     static int __init mod_init(void)
>     {
>         dev_t devno;
>         my_class = class_create(THIS_MODULE, DRIVER_NAME);
>         ret = alloc_chrdev_region(&devno, 0, MAX_DEVICES, DRIVER_NAME);
> 
>         my_major = MAJOR(devno);
> 
>         ...
>     }
> 
> (Note that for brevity I'm omitting a lot of boilerplate/error handling,
> etc. But you can assume it's all there).
> 
> My driver is also a network driver; in fact, it's *primarily* a network
> driver and it provides a char device file that is used to configure the
> hardware. I am creating the char device whenever the network device is first
> opened (e.g. 'netdev_open' below is the 'ndo_open' field of the 'struct
> netdev_ops'):
> 
>     struct private_data {
>         struct cdev cdev;
>         ...
>     }
> 
>     static int netdev_open(struct net_device *dev)
>     {
>         struct private_data *priv = netdev_priv(dev);
>         dev_t devno;
>         int minor;
>         struct device *d;
> 
>         minor = ida_alloc_max(&ida, MAX_DEVICES, GFP_KERNEL);
> 
>         devno = MKDEV(my_major, minor);
>         cdev_init(&priv->cdev, &my_fops);
>         cdev_add(&priv->cdev, devno, 1);
> 
>         /* This should create a device node with the same name as the
>          * network interface, e.g. foo0
>          */
>         d = device_create(my_class, NULL, devno, priv, dev->name);
>         if (IS_ERR(d)) {
>             ...
>         }
> 
>         ...
>     }
> 
> Again, I'm omitting the error checking for the sake of brevity, but it is
> there in the actual code. This function runs successfully and the network
> device is successfully opened. The 'device_create' function does not return
> an error, but there is nothing beneath /dev as I would expect.
> 
> I'm really stumped here because everything I've been able to find online
> says that 'device_create' ought to create that device file. I can see my
> class under /sys/class/ and that directory contains a directory with the
> name of the device:
> 
>     $ ls -1 /sys/class/my_class/
>     foo0
> 
> so it looks like the char device *is* being created, there's just no
> corresponding entry under /dev.

Is your char device listed in /sys/dev/char/ ?

If not, then you have something wrong with your call to device_create().

If so, then you need to look at whatever tool is creating your device
nodes in /dev.  Usually the kernel handles this with devtmpfs, but I do
not know what your system uses for this.

Do you have a pointer to the real source code anywhere to be able to see
it better to see if you are doing something wrong with the call to
device_create()?

Also, why a full major?  Why not just use the misc_dev api instead that
does all of the above "housekeeping" for you automagically?

thanks,

greg k-h



More information about the Kernelnewbies mailing list