can not find the driver in /proc/device - linux

I want to compile a device driver in kernel, and I configure it with *, (not in module ). After the compilation, I can't see the device in /proc/device. Also I check the output of make bzImage, the driver has been compiled. Do I need to delete the two lines:
module_init(mydriver_init);
module_exit(mydriver_exit);

There is not enough information to understand your problem. You should show some code.
Anyway, /proc/devices does not show all kernel module. It shows devices, maybe your driver is not registering a device.
You can put some printk() in your code and read it with the command dmesg from your terminal. If your read your print, your module is loaded.
Evan if you do not compile a module as module, but you built it within the kernel, functions
module_init(mydriver_init);
module_exit(mydriver_exit);
must be there. mydriver_init will be executed when the kernel load your driver, module_exit will be executed when the kernel unload your driver.

The /proc/devices file which is read-only doesn't seem to be editable or viewable using editors like VIM. So try 'cat /proc/devices', your device may show up then.

Related

How to read the external timer counter on the BeagleBone Black?

I need to count the transitions of a 50KHz binary signal using a BBB. I think using the TIMER4 triggered by the external signal connected to the pin P8.07 would be the easiest way.
So, I issued the following commands to load the proper cape and setup the pin as a timer :
./config-pin overlay cape-universaln
./config-pin P8.07 timer
Everything seems to work and nothing appears in dmesg.
My question is : How can I read the value of TIMER4 ? I looked in SysFs and find nothing interesting. Nothing in /dev as well. How can I retrieve the value of the timer counter I just setup ? I'm open to a C/C++ solution as well, but I would like to avoid doing kernel-space programming.
I'm using the latest Ubuntu Linux for BeagleBone, kernel 4.1.10-ti-r21.
With a little googling I see a pps driver for the AM335x DMTimer subsystem here: https://github.com/ddrown/pps-gmtimer
It looks like it hasn't been merged upstream and the README gives instructions on building it into the 3.8 kernel - you could revert back to 3.8, or you could adapt that for 4.1, in which case you may need to tweak the Device Tree overlay as well for the newer version of the dtc compiler that's in 4.1.
You could also write a pulse counter firmware for the PRU (with only a 50KHz input it wouldn't need to be very optimized at all to catch every pulse). You could send a signal to the ARM every so often and catch that in your userspace program.
Another option would be to directly access the DMTimer registers from userspace using mmap to map the /dev/mem file (example of this method for GPIO here), but that's a pretty "hacky" way to do it, and it's generally frowned upon in the GNU/Linux world to do that sort of stuff from userspace instead of from kernal space.

Difficulties backporting Linux kernel driver

I'm trying to backport a Linux kernel driver (the PCF85063 RTC, specifically) from the 3.17+ kernel into a 3.14 kernel I'm using, and I'm running into a few issues. I don't have any experience with adding/modifying kernel drivers, so I'm not sure if what I've done so far is correct:
I took the rtc-pcf85063.c file from the newer kernel, and added it to my drivers/rtc/ directory in the kernel source.
I added the following line to drivers/rtc/Makefile:
obj-$(CONFIG_RTC_DRV_PCF85063) += rtc-pcf85063.o
I added this snippet to drivers/rtc/Kconfig
config CONFIG_RTC_DRV_PCF85063
tristate "NXP PCF85063"
help
If you say yes here, you get support for the NXP PCF85063 RTC.
From my understanding, that should be all it takes to add driver support for the new RTC. When I execute make menuconfig, I can see my new RTC entry under Device Drivers > Real Time Clock, labeled as NXP PCF85063 with the correct help information. So it's clear that the third step above was successful.
The problem is, when I include this driver (by selecting it in menuconfig and saving/exiting) in my kernel build, it doesn't actually get built in. If I deploy the kernel and read /lib/modules/3.14.17/modules.builtin, the new driver is nowhere to be found. Also, if I check drivers/rtc/ after building the kernel, there are object files for every RTC driver included through menuconfig except the new one; the kernel isn't even compiling the driver.
I found one interesting thing that might give some hint as to what's going on. When I go to include/config in the linux source after running menuconfig, I have a bunch of directories, some of which correspond to drivers. There's an rtc directory, and when I navigate to include/config/rtc/drv, there's a header file for every RTC driver included in the build except the one I added.
The thing is, the header file corresponding to the new driver is in include/config; it's hidden away in include/config/config/rtc/drv. It looks like menuconfig isn't treating the new driver as a regular RTC driver.
I know this is a pretty specific problem, but I was hoping that someone might notice that I'm missing a step or going about this the wrong way. Thanks.

Hard time in understanding MODULE_DEVICE_TABLE(usb, id_table) usage

I have a hard time understanding the exact usage of MODULE_DEVICE_TABLE(usb, id_table)
AFAIK this will generate the map files that will be used later by modprobe whenever a new device is inserted, it will match it against those map files and load the module if it matches.
But my misunderstanding is "isn't the module loaded anyway?"
I mean I already loaded it when I did insmod module-name. or am I missing something?
It is usually used to support hot-plugging, by loading/inserting the driver for a device if not already loaded.
There is a similar question here: Detect the presence of a device when it's hot plugged in Linux
(From my ans)
It works as follows:
Each driver in the code exposes its vendor/device id using:
MODULE_DEVICE_TABLE(of, omap_mcspi_of_match);
At compilation time the build process extracts this infomation from all the drivers and prepares a device table.
When you insert the device, the device table is referred by the kernel and if an entry is found matching the device/vendor id of the added device, then its module is loaded and initialized.
According to Linux Device Drivers:
MODULE_DEVICE_TABLE is used to generate map files by depmod program;
When device is hot-plugged, bus driver generates hotplug event. Kernel calls /sbin/hotplug with appropriate environmental variables set;
Given map files and information from environment, /sbin/hotplug decides which module to load and actually loads it. If the module is already loaded, it's OK.
I should mention again that this mechanism just ensures that needed module is in-place when device is plugged. That doesn't link module with that device or anything else. Just loads module.
To check if driver is OK for specific device, match() function from bus_type is used.
Here is how I understands the things [Xbuntu 14.04 compatible].
Once we wrote a module, we can either load it manually, or automatically.
Manually -> insmod modulename.ko or modprob modulename.ko
Automatically-> There are multiple ways.
copy to /lib/modules/`uname -r`/kernel/modulename.ko and update /etc/modules. System will load the module while booting.
Write a script/command to load the module.ko for an specific harware add/change/remove event in a udev rule /etc/udev/rules.d/10-local.rules. You can do both load/unload using this method.
Code your module with MODULE_DEVICE_TABLE registration. Then load your modulename.ko once and run depmod command [sudo depmod -a] to add the new module to /lib/modules/3.16.0-34-generic/modules.alias /lib/modules/3.16.0-34-generic/modules.dep files. As I know, system will load only if the module is not loaded.
You can monitor module loading/unloading using udev events using :
udevadm monitor
command.

Removing a device driver module that was statically compiled

I compiled the linux kernel with serial device driver statically i.e obj-y.
Now I'm working on a simple serial driver and I want to test it, but since the module is loaded when the kernel boots up, the IO port regions (0x3f8 and onwards) are registered to the serial module. I need to remove(unregister) it so that I can allocate it to my driver.
So, is there any way to remove the statically linked device driver ? or should I recompile the whole kernel :/
You should recompile the whole kernel and make this driver an obj-m.
Once it's loaded (either done automatically by modprobe or manually with insmod), you may remove it (using rmmod), modify the code, compile it again and load it again.
Of course, if there was some critical error that was not handled properly during the driver's operation, the whole kernel will be in an unstable state and you will have to reboot (until you fix what causes this).

How can I get edge events via GPIO on Linux without a busy-loop?

I'm working an a system with embedded Linux (Kernel 2.6.31).
It is a AT91SAM9G20 chip inside, and some of the Pins are forwarded to the outside.
Now I want to use them as GPIO Inputs.
I read the gpio.txt documentation about using the GPIOs via filesystem, and that works very well 'til here. I connected some switches to the gpio-pins and I can see the result in /sys/class/gpio/gpioX/value. But now I'd like to react on a change without busy-waiting in a loop. (i.e echo "Switch1 was pressed").
I guess I need interrupts here, but I couldn't find out how to use them without writing my own kernel driver. I'm relatively new to Linux and C (I normally program in Java), so I'd like to handle the Interrupts via sysfs too. But my problem is, that there is no "edge"-file in my GPIO directory (I guess because this is only since Kernel version 2.6.33+). Is that right? Instead of "edge" I've got a uevent file in there, which is not described in gpio.txt.
In the gpio.txt documentation there was a Standard Kernel Driver mentioned: "gpio_keys". Is it possible to use this for my problem?
I guess it would be better to work with this driver than allowing a userspace program to manipulate kernel tasks.
I found a lot of codesnippets for writing my own driver, but I wasn't even able to find out which of the 600 gpio.h files to include, and how to refer to the library (cross compiler couldn't find the gpio.h file).
Sorry for newbie questions, I hope you could give me some advices.
Thanks in advance
See this for an example on how to do that. Basically, the thing you're missing is the usage of the select or poll system calls.

Resources