* Device file not appearing
@ 2021-03-17 15:52 Gregory Anders
2021-03-17 15:59 ` Greg KH
0 siblings, 1 reply; 9+ messages in thread
From: Gregory Anders @ 2021-03-17 15:52 UTC (permalink / raw)
To: kernelnewbies
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.
Anyway, I know that's a lot of info. If you've made it this far, thanks
for reading. If you have any insight/advice/suggestions for me I'd
greatly appreciate it!
Thanks,
Greg
_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Device file not appearing
2021-03-17 15:52 Device file not appearing Gregory Anders
@ 2021-03-17 15:59 ` Greg KH
2021-03-17 16:13 ` Gregory Anders
0 siblings, 1 reply; 9+ messages in thread
From: Greg KH @ 2021-03-17 15:59 UTC (permalink / raw)
To: kernelnewbies
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
_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Device file not appearing
2021-03-17 15:59 ` Greg KH
@ 2021-03-17 16:13 ` Gregory Anders
2021-03-17 16:16 ` Greg KH
0 siblings, 1 reply; 9+ messages in thread
From: Gregory Anders @ 2021-03-17 16:13 UTC (permalink / raw)
To: Greg KH; +Cc: kernelnewbies
On Wed, 17 Mar 2021 16:59:08 +0100, Greg KH <greg@kroah.com> wrote:
>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.
Indeed it is. I am working with a fairly minimal system on a Xilinx
Microblaze soft-core CPU. I have udev installed, but I'm not sure about
devtmpfs. I'll start digging in that direction and see what I find.
>Also, why a full major? Why not just use the misc_dev api instead that
>does all of the above "housekeeping" for you automagically?
Simply because I wasn't aware of the misc_dev API :) But that does look
like a nice abstraction that will save me some boilerplate, so thanks
for pointing that out.
Thanks,
Greg
_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Device file not appearing
2021-03-17 16:13 ` Gregory Anders
@ 2021-03-17 16:16 ` Greg KH
2021-03-17 16:56 ` Gregory Anders
0 siblings, 1 reply; 9+ messages in thread
From: Greg KH @ 2021-03-17 16:16 UTC (permalink / raw)
To: kernelnewbies
On Wed, Mar 17, 2021 at 10:13:22AM -0600, Gregory Anders wrote:
> On Wed, 17 Mar 2021 16:59:08 +0100, Greg KH <greg@kroah.com> wrote:
> > 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.
>
> Indeed it is. I am working with a fairly minimal system on a Xilinx
> Microblaze soft-core CPU. I have udev installed, but I'm not sure about
> devtmpfs. I'll start digging in that direction and see what I find.
udev does not do device node creation anymore (as of a decade or so),
you should make sure devtmpfs is mounted at /dev/ in order for this to
work properly.
good luck!
greg k-h
_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Device file not appearing
2021-03-17 16:16 ` Greg KH
@ 2021-03-17 16:56 ` Gregory Anders
2021-03-17 17:05 ` Gregory Anders
2021-03-17 17:15 ` Greg KH
0 siblings, 2 replies; 9+ messages in thread
From: Gregory Anders @ 2021-03-17 16:56 UTC (permalink / raw)
To: Greg KH; +Cc: kernelnewbies
On Wed, 17 Mar 2021 17:16:04 +0100, Greg KH <greg@kroah.com> wrote:
>udev does not do device node creation anymore (as of a decade or so),
>you should make sure devtmpfs is mounted at /dev/ in order for this to
>work properly.
>
>good luck!
>
>greg k-h
I switched over to using the miscdevice API and the situation is the
same. Nothing under /dev, but I can see my device under /sys/dev/char
(it now also exists under /sys/devices/virtual/misc/, as expected).
I verified that devtmpfs is enabled in the kernel config
(CONFIG_DEVTMPFS=y and CONFIG_DEVTMPFS_MOUNT=y) and also see that it is
mounted on /dev:
# cat /proc/mounts
root@xilinx-kcu105-2020_2:~# cat /proc/mounts
192.168.0.116:/data/nfs/root / nfs rw,relatime,vers=3,rsize=4096,wsize=4096,namlen=255,hard,nolock,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=192.168.0.116,mountvers=3,mountproto=tcp,local_lock=all,addr=192.168.0.116 0 0
devtmpfs /dev devtmpfs rw,relatime,size=1026312k,nr_inodes=185478,mode=755 0 0
proc /proc proc rw,relatime 0 0
sysfs /sys sysfs rw,relatime 0 0
tmpfs /run tmpfs rw,nosuid,nodev,mode=755 0 0
tmpfs /var/volatile tmpfs rw,relatime 0 0
tmpfs /dev tmpfs rw,relatime,size=64k,mode=755 0 0
devpts /dev/pts devpts rw,relatime,mode=600,ptmxmode=000 0 0
I notice that it lists /dev as both devtmpfs (line 2) as well as tmpfs
(the second line from the bottom). Could that be an issue? I'm not sure
how or why /dev is being mounted as tmpfs in addition to devtmpfs.
Thanks,
Greg
_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Device file not appearing
2021-03-17 16:56 ` Gregory Anders
@ 2021-03-17 17:05 ` Gregory Anders
2021-03-17 17:15 ` Greg KH
1 sibling, 0 replies; 9+ messages in thread
From: Gregory Anders @ 2021-03-17 17:05 UTC (permalink / raw)
To: Greg KH, kernelnewbies
On Wed, 17 Mar 2021 10:56:34 -0600, Gregory Anders <greg@gpanders.com> wrote:
>I switched over to using the miscdevice API and the situation is the
>same. Nothing under /dev, but I can see my device under /sys/dev/char
>(it now also exists under /sys/devices/virtual/misc/, as expected).
>
>I verified that devtmpfs is enabled in the kernel config
>(CONFIG_DEVTMPFS=y and CONFIG_DEVTMPFS_MOUNT=y) and also see that it
>is mounted on /dev:
>
> # cat /proc/mounts
> root@xilinx-kcu105-2020_2:~# cat /proc/mounts
> 192.168.0.116:/data/nfs/root / nfs rw,relatime,vers=3,rsize=4096,wsize=4096,namlen=255,hard,nolock,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=192.168.0.116,mountvers=3,mountproto=tcp,local_lock=all,addr=192.168.0.116 0 0
> devtmpfs /dev devtmpfs rw,relatime,size=1026312k,nr_inodes=185478,mode=755 0 0
> proc /proc proc rw,relatime 0 0
> sysfs /sys sysfs rw,relatime 0 0
> tmpfs /run tmpfs rw,nosuid,nodev,mode=755 0 0
> tmpfs /var/volatile tmpfs rw,relatime 0 0
> tmpfs /dev tmpfs rw,relatime,size=64k,mode=755 0 0
> devpts /dev/pts devpts rw,relatime,mode=600,ptmxmode=000 0 0
>
>I notice that it lists /dev as both devtmpfs (line 2) as well as tmpfs
>(the second line from the bottom). Could that be an issue? I'm not
>sure how or why /dev is being mounted as tmpfs in addition to
>devtmpfs.
>
>Thanks,
>
>Greg
One other data point: there are 3 other misc devices on the system, and
all of them are correctly listed under /dev:
# ls -1 /sys/class/misc
cpu_dma_latency
loop-control
foo0
vga_arbiter
# ls -1 /dev/{cpu_dma_latency,loop-control,vga_arbiter}
/dev/cpu_dma_latency
/dev/loop-control
/dev/vga_arbiter
Greg
_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Device file not appearing
2021-03-17 16:56 ` Gregory Anders
2021-03-17 17:05 ` Gregory Anders
@ 2021-03-17 17:15 ` Greg KH
2021-03-17 18:26 ` Gregory Anders
1 sibling, 1 reply; 9+ messages in thread
From: Greg KH @ 2021-03-17 17:15 UTC (permalink / raw)
To: kernelnewbies
On Wed, Mar 17, 2021 at 10:56:34AM -0600, Gregory Anders wrote:
> On Wed, 17 Mar 2021 17:16:04 +0100, Greg KH <greg@kroah.com> wrote:
> > udev does not do device node creation anymore (as of a decade or so),
> > you should make sure devtmpfs is mounted at /dev/ in order for this to
> > work properly.
> >
> > good luck!
> >
> > greg k-h
>
> I switched over to using the miscdevice API and the situation is the same.
> Nothing under /dev, but I can see my device under /sys/dev/char (it now also
> exists under /sys/devices/virtual/misc/, as expected).
Then this is a userspace issue, not the kernel :)
> I verified that devtmpfs is enabled in the kernel config (CONFIG_DEVTMPFS=y
> and CONFIG_DEVTMPFS_MOUNT=y) and also see that it is mounted on /dev:
>
> # cat /proc/mounts
> root@xilinx-kcu105-2020_2:~# cat /proc/mounts
> 192.168.0.116:/data/nfs/root / nfs rw,relatime,vers=3,rsize=4096,wsize=4096,namlen=255,hard,nolock,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=192.168.0.116,mountvers=3,mountproto=tcp,local_lock=all,addr=192.168.0.116 0 0
> devtmpfs /dev devtmpfs rw,relatime,size=1026312k,nr_inodes=185478,mode=755 0 0
> proc /proc proc rw,relatime 0 0
> sysfs /sys sysfs rw,relatime 0 0
> tmpfs /run tmpfs rw,nosuid,nodev,mode=755 0 0
> tmpfs /var/volatile tmpfs rw,relatime 0 0
> tmpfs /dev tmpfs rw,relatime,size=64k,mode=755 0 0
> devpts /dev/pts devpts rw,relatime,mode=600,ptmxmode=000 0 0
>
> I notice that it lists /dev as both devtmpfs (line 2) as well as tmpfs (the
> second line from the bottom). Could that be an issue? I'm not sure how or
> why /dev is being mounted as tmpfs in addition to devtmpfs.
Looks like you have mounted tmpfs on top of devtmpfs, which seems very
odd. Try unmounting the tmpfs instance and see if the node really is
there in devtmpfs.
Or better yet, mount devtmpfs somewhere else right now to see if the
node is there.
Good luck with your userspace mount maze!
greg k-h
_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Device file not appearing
2021-03-17 17:15 ` Greg KH
@ 2021-03-17 18:26 ` Gregory Anders
0 siblings, 0 replies; 9+ messages in thread
From: Gregory Anders @ 2021-03-17 18:26 UTC (permalink / raw)
To: Greg KH; +Cc: kernelnewbies
On Wed, 17 Mar 2021 18:15:27 +0100, Greg KH <greg@kroah.com> wrote:
>Looks like you have mounted tmpfs on top of devtmpfs, which seems very
>odd. Try unmounting the tmpfs instance and see if the node really is
>there in devtmpfs.
>
>Or better yet, mount devtmpfs somewhere else right now to see if the
>node is there.
>
>Good luck with your userspace mount maze!
>
>greg k-h
Ok I finally tracked down what was going on. The embedded distribution I
am using uses mdev. mdev has an init script that mounts tmpfs on /dev,
which is why devtmpfs wasn't working as expected.
mdev requires the kernel option CONFIG_UEVENT_HELPER=y which was not
enabled in my configuration (it even has a scary help description,
something along the lines of "this should not be used", so I didn't
think to enable it until I saw it mentioned somewhere else). After
enabling that, the device file appears under /dev.
Thanks for your help Greg!
_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
^ permalink raw reply [flat|nested] 9+ messages in thread
* Device file not appearing
@ 2021-03-16 20:25 Gregory Anders
0 siblings, 0 replies; 9+ messages in thread
From: Gregory Anders @ 2021-03-16 20:25 UTC (permalink / raw)
To: kernelnewbies
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.
Anyway, I know that's a lot of info. If you've made it this far, thanks
for reading. If you have any insight/advice/suggestions for me I'd
greatly appreciate it!
Thanks,
Greg
_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2021-03-21 18:48 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-17 15:52 Device file not appearing Gregory Anders
2021-03-17 15:59 ` Greg KH
2021-03-17 16:13 ` Gregory Anders
2021-03-17 16:16 ` Greg KH
2021-03-17 16:56 ` Gregory Anders
2021-03-17 17:05 ` Gregory Anders
2021-03-17 17:15 ` Greg KH
2021-03-17 18:26 ` Gregory Anders
-- strict thread matches above, loose matches on Subject: below --
2021-03-16 20:25 Gregory Anders
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).