Basic Linux dmesg questions - linux

and thanks for looking at this question.
I am porting a Linux (2.6.37) driver between bus standards (PLB -> AXI) to be precise for a Xilinx FPGA-SoC. The device driver is compiled inline in the tree. I have a few questions that I am sure you guys can help me.
What listing in the Linux kernel tree, allows a device to print the device_init_ string on dmesg ? What file is required for the listing ?
Normally when a device driver is compiled outside the tree, the extension used (normally) is *.ko, is this the case when the device driver is compiled within the tree and merged using "make modules" ?
EDITS for Clarity
Suppose you have a device called "foo", that has to be compiled within the tree. I am observing that "foo" is printing dmesg strings for PLB but not for AXI. I was intending to ask how the device gets added to 'init' ? Which file holds the entry for "foo" that tells init that "foo" has to be loaded ?
For larger sense, foo = xilinx_hwicap
Thanks
RRS
P.S Thanks for your patience

printk(9) prints to the system message ring.
All modules in 2.6+, regardless of location, end in ".ko".

Related

How can I determine what MTD flash device is installed (e.g. get the ID or serial number)?

Using uClinux we have one of two flash devices installed, a 1GB flash or a 2GB flash.
The only way I can think of solving this is to somehow get the device ID - which is down the in the device driver code, for me that is in:
drivers/mtd/devices/m25p80.c
I have been using the command mtdinfo (which comes from mtdutils binaries, derived from mtdinfo.c/h). There is various information stored in here about the flash partitions including flash type 'nor' eraseblock size '65536', etc. But nothing that I can identify the chip with.
Its not very clear to me how I can get information from "driver-land" into "user-land". I am looking at trying to extend the mtdinfo command to print more information but there are many layers...
What is the best way to achieve this?
At the moment, I have found no easy way to do this without code changes. However I have found an easy code change (probably a bit of a hack) that allows me to get the information I need:
In the relevant file (in my case drivers/mtd/devices/m25p80.c) you can call one of the following:
dev_err("...");
dev_alert("...");
dev_warn("...");
dev_notice("...");
_dev_info("...");
Which are defined in include/Linux/device.h, so they are part of the Linux driver interface so you can use them from any driver.
I found that the dev_err() and devalert() both get printed out "on screen" during run time. However all of these device messages can be found in /var/log/messages. Since I added messages in the format: dev_notice("JEDEC id %06x\n", jedecid);, I could find the device ID with the following command:
cat /var/log/messages | grep -i jedec
Obviously using dev_err() ordev_alert() is not quite right! - but dev_notice() or even _dev_info() seem more appropriate.
Not yet marking this as the answer since it requires code changes - still hoping for a better solution if anyone knows of one...
Update
Although the above "solution" works, its a bit crappy - certainly will do the job and good enough for mucking around. But I decided that if I am making code changes I may as well do it properly. So I have now implemented changes to add an interface in sysfs such that you can get the flash id with the following command:
cat /sys/class/m25p80/m25p80_dev0/device_id
The main function calls required for this are (in this order):
alloc_chrdev_region(...)
class_create(...)
device_create(...)
sysfs_create_group(...)
This should give enough of a hint for anyone wanting to do the same, though I can expand on that answer if anyone wants it.

How to deal with linux kernel drivers (for newbies)

I am trying to undestand how to USE linux kernel drivers. One day I wrote linux kernel module for handling interrupts from gpio. Built it with "make" command and loaded it with "insmod" and it worked. But now I am trying to use this ov5642 camera driver.I downloaded the source code. made "make" command in folder with sources and when it built I used "insmod" command to load it. It is now listed in already loaded modules list but I have got no idea how to get grabbed frames.
How can I make it work and access its output ?
In order to capture frames from the module, you need to "probe" your driver with a platform device (i.e. you have to create a platform device in order to call "ov5642_probe" function). If the probe function is being called, and ends successfully reaching to "return 0", you will get a print "Chip ID 0x5642 detected" in dmesg. (You can easily check weather the probe function is being called or not by putting a simple "printk(KERN ERR "### my probe function is being called")" at line number 935 in probe function and check in dmesg. If it is being called, you have to interface the camera properly in order to probe driver successfully.
If probe function fails (i.e. being called but not reaching till "return 0"), then there should be problem with reading the registers of ov5642. Check the i2c connections and power supplies of camera properly (and make sure its power on sequence is performed as mentioned in datasheet) if you get "Chip ID" other than 0x5642 or i2c read fails.
If the probe function is not being called, then you need to create a proper platform_device.
Assuming you are doing this on a custom board where ov5642 module is interfaced.
If you get "Chip ID 0x5642 detected" in dmesg, then you should try with "v4l-utils" package. There are many options available in v4l2-ctl command where you can set format, query capabilities, start stream, grab frame. If you are unable to install v4l-utils on your board, then, you should try https://gist.github.com/maxlapshin/1253534. You can also refer to Documentation/video4linux/ on lxr online or any kernel source offline if you are interested in developing a camera driver.
If you are a newbie, and you want to learn to deal with kernel drivers, refer to http://www.makelinux.net/ldd3/ and specially platform driver documentation under Documentation/driver-model/platform.txt on lxr for creating and probing a platform driver.

what is the OSX version of Linux's /dev/usb/lp0?

I'm writing to a centronics cable and blinking some LEDs via a simple "bufferized" circuit.
I'm able to write out the bits via C code referencing the device location on /dev/usb/lp0 on an Ubuntu machine.
However, I'd like to be able to do this on OSX Mavericks. I don't see the same type of device file as I do in Linux.
i.e. is there an OSX analog to /dev/usb/lp0 on Linux?
Thanks much.
Under the concept of "everything's a file" lp0 is just a special file that allows raw access to a device, in this case a 'special character file' for the first parallel device. The same would exist on OSX if a driver was present that matched the device, or something like /dev/parport0. OSX has a pretty limited collection of parallel drivers though. You could try to fudge it - create a 'character' device file pointing it to some generic parallel driver with mknod.
e.g. mknod lp0 c x y where x an y are the major and minor numbers for the device type. Typically you find these numbers in the documentation/devices.txt file on linux, not sure where this info is on OSX though.
I've seen devices handle this using generic printer drivers, such as a "gadget printer":
https://www.kernel.org/doc/Documentation/usb/gadget_printer.txt
(my initial assumption)
In this case the device will actually show up on the system as a printer. You can find a list of printers and their location using CUPS utilities like lpstat:
https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/lpstat.1.html#//apple_ref/doc/man/1/lpstat
There's also the environment variables LPDEST and PRINTER which should list the default print location:
echo $LDPEST

How to get Linux kernel modules list from user space C code?

I want to get the list of kernel modules by C code, and later on print their version.
From a script this is simple:
cat /proc/modules
lsmod
and later on, run for all drivers found:
modinfo driver_name
From C code, I can open /proc/modules, and analyze the data there, but is there a simpler way of reading this drivers list?
From C code, I can open /proc/modules, and analyze the data there, but is there a simpler way of reading this drivers list?
Depends on your definition of simple. The concept in Unix land of everything being a file does make everything simpler in one respect, because:
int fd = open("/proc/modules" | O_RDONLY);
while ( read(fd, &buffer, BUFFER_LIMIT) )
{
// parse buffer
}
close(fd);
involves the same set of function calls as opening and reading any file.
The alternative mechanism would be for the kernel to allocate some memory in your process' address space pointing to that information (and you could probably do this with a custom system call) but there's really no need - as you've seen, this way works very well not just with C, but with scripts also.

Create UNIX "special character" file

Suppose I want to create, in the spirit of /dev/zero, a file /dev/seven that produces the character '7' whenever it is read from. How should I go about doing something like this? Would I need to modify the kernel?
Yes, you'd need to create a driver for that special character device.
For linux, I'd suggest you read Linux Device Drivers by Jonathan Corbet, Alessandro Rubini, and Greg Kroah-Hartman. (Chapter 3 talks about char drivers, but do read at least the first two chapters also.)
A device driver is not necessary, a fifo special file plus a user program generating the stream of 7 is perfectly able to provide this behavior.
You'll need about a five line shell script, all told.
There's a short example of creating a device driver for Linux here, which might help to get you started:
http://www.freesoftwaremagazine.com/articles/drivers_linux

Resources