Page 1 of 1

can not write to a new device I just created

Posted: Tue Oct 13, 2020 12:32 am
by ggodw000
I made or what I think I made is a minimally functioning device driver which has read/write capability following the instructions in "linux device drivers" 3rd ed. by Jonathan Corbet and 2 others.

The device itself obviously not a hardware device and writing and reading to device is implemented by implementing its own device memory created in kernel. So far it is compiling OK meaning all the functions implemented (well literally copied from gituhb starpos) correctly. The starpos project, which has full source for scull project, I noticed had some build issue so I am just moving over the functions from there one - by -one. The driver's load script will assign major number of the device and will create representative device in /dev/scull and several others.

Now i added some of my own code by implementing it dkms compatible and I can see it loads fine.
Toward the end of its device read/write implementation, the book instructs to try device's I/O functions by standard linux file operations i.e.
ls -l > /dev/scull0
but returns back to terminal with following error:

ls -l > /dev/scull
-bash: /dev/scull: No such device or address

I am not sure what I should check???

Re: can not write to a new device I just created

Posted: Thu Oct 15, 2020 11:38 am
by PeterX
I don't know much about the Linux kernel internals.

I guess you get better answers at Linuxfoundation's forum in the kernel development subforum:
https://forum.linuxfoundation.org/categ ... evelopment

Greetings
Peter

Re: can not write to a new device I just created

Posted: Mon Oct 26, 2020 10:07 pm
by ggodw000
posted no response yet.
How about if I post source code github here? https://github.com/gggh800/scull-dev.git
downloading and testing is extremely easy:
On ubuntu1804, in 5.4.x -ish kernel, install dkms: apt install dkms
download and use dkms.sh script to build and install.
there is a load_scull script to do the rest in src/
ls -l > /dev/scull reproduces problem.

Re: can not write to a new device I just created

Posted: Tue Oct 27, 2020 12:00 am
by linuxyne
register_chrdev_region and alloc_chrdev_region usage is mutually exclusive.

scull_major shouldn't remain 0.

Re: can not write to a new device I just created

Posted: Tue Oct 27, 2020 10:34 pm
by ggodw000
After initialization it did not remain 0 for sure. I verified through
ls -l /dev/scull* and also through cat /proc/devices | grep -i scull.
Have you tried on your system?

Re: can not write to a new device I just created

Posted: Tue Oct 27, 2020 11:09 pm
by linuxyne

Code: Select all

result = alloc_chrdev_region(&dev, scull_minor, scull_nr_devs,  "scull");
alloc_chrdev_region returns the major# in dev. Your code doesn't update the scull_major variable.

Re: can not write to a new device I just created

Posted: Wed Oct 28, 2020 11:34 pm
by ggodw000
i took a closer look at the driver.

I see following is redundant, since scull_major is 0 statically declared in the driver.
There is problem with this approach, since dev is initialized to be 0, possibly scull_major=MAJOR(dev) appears to initialize the scull_major as 0.

if (scull_major) {
dev = MKDEV(scull_major, scull_minor);
result = register_chrdev_region(dev, scull_nr_devs, "scull");
} else {
result = alloc_chrdev_region(&dev, scull_minor, scull_nr_devs,
"scull");
scull_major = MAJOR(dev);
}

It seems problem lies in the fact that once driver loaded, I can see system assigns device i.e. 240 in this case (from looking at /proc/devices) but inside the driver, the scull_major is maintained to be 0.
There seems to be need to get the system assigned driver inside the driver instead of maintaining statically assigned 0, i wonder how?
scull_load script can easily get that number by scanning the /prod/devices.

alloc_chrdev_region seems to be affecting scull_minor.

Re: can not write to a new device I just created

Posted: Thu Oct 29, 2020 12:29 am
by ggodw000
Got some progress, no longer same error still another error but that is I call progress :)
Key was to move the scull_major = MAJOR(dev); call to after alloc_chrdev_region.
Then the scull_major gets updated with the number 240 from system and subsequent initailization was using that number.

[ 27.725570] scull, world. Build No. 6
[ 27.725615] param_scull_major is an integer: 3
[ 27.725616] 3. dev: 0
[ 27.725847] 4. dev: 251658240
[ 27.725849] acquired major number, result: 0
[ 27.725850] 2. scull_major/minor: 240 0
[ 27.725852] scull_setup_cdev: entered...
[ 27.725854] major minor index: 240 0 0
[ 27.725855] devno: 251658240
[ 27.725857] scull_setup_cdev: entered...
[ 27.725858] major minor index: 240 0 1
[ 27.725859] devno: 251658241
[ 27.725860] scull_setup_cdev: entered...
[ 27.725861] major minor index: 240 0 2
[ 27.725862] devno: 251658242
[ 27.725863] scull_setup_cdev: entered...
[ 27.725864] major minor index: 240 0 3
[ 27.725865] devno: 251658243
root@guyen-Standard-PC-i440FX-PIIX-1996:/git.co/dev-learn/device-drivers/src# ls -l /dev/ | grep scull
lrwxrwxrwx 1 root root 6 Oct 28 23:27 scull -> scull0
crw-rw-r-- 1 root staff 240, 0 Oct 28 23:27 scull0
crw-rw-r-- 1 root staff 240, 1 Oct 28 23:27 scull1
crw-rw-r-- 1 root staff 240, 2 Oct 28 23:27 scull2
crw-rw-r-- 1 root staff 240, 3 Oct 28 23:27 scull3
lrwxrwxrwx 1 root root 10 Oct 28 23:27 scullpipe -> scullpipe0
crw-rw-r-- 1 root staff 240, 4 Oct 28 23:27 scullpipe0
crw-rw-r-- 1 root staff 240, 5 Oct 28 23:27 scullpipe1
crw-rw-r-- 1 root staff 240, 6 Oct 28 23:27 scullpipe2
crw-rw-r-- 1 root staff 240, 7 Oct 28 23:27 scullpipe3
crw-rw-r-- 1 root staff 240, 11 Oct 28 23:27 scullpriv
crw-rw-r-- 1 root staff 240, 8 Oct 28 23:27 scullsingle
crw-rw-r-- 1 root staff 240, 9 Oct 28 23:27 sculluid
crw-rw-r-- 1 root staff 240, 10 Oct 28 23:27 scullwuid
root@guyen-Standard-PC-i440FX-PIIX-1996:/git.co/dev-learn/device-drivers/src# cat /proc/devices | grep scull
240 scull
root@guyen-Standard-PC-i440FX-PIIX-1996:/git.co/dev-learn/device-drivers/src# ls -l > /dev/scull
ls: write error: Invalid argument
root@guyen-Standard-PC-i440FX-PIIX-1996:/git.co/dev-learn/device-drivers/src#