Hardware recognition in user space Linux - linux

I want to be able to inspect my Linux machine hardware in C.
How do I get the information that appear in dmesg in C ?
For example, for keyboard the message is input: AT Translated Set 2 keyboard as /devices/platform/i8042/serio0/input/input0
I want to get in my program the label, AT Translated Set 2, and the path, /devices/platform/i8042/serio0/input/input0.
Any idea how to do so ?
amit

You can also look at the contents of files in /proc.
/proc/version, /proc/ioports, /proc/iomem, /proc/meminfo, and others have a lot of information in them.
The files under /proc/bus have additional information about the system's hardware devices.
I'd also recommend looking at the source code for usbutils and pciutils for example code to get the output from the lsusb and lspci commands respectively.

It uses the klogctl call.
Best thing is to read the source code yourself, it can be downloaded here: util-linux

You would want to use libhal, and connect to the hal daemon. If HAL isn't there, look for a mounted sysfs partition. Check out /sys/devices, or work backwards through /sys/bus.
If neither HAL nor sysfs is available, reconsider your approach or restrict your scope.

Related

Source code of keyboard driver of linux

I have been working on making my own keyboard driver for linux. So I came accross these two links: usbkbd.c and atkbd.c.
Now I am
confused which of these is the actual code driving my keyboard at the present. As I see it atkbd.c is quite gory and there is a conversion
of scancodes to keycodes. So it should be the code, though I am not sure.
If atkbd.c is the code, then what is the other code for?
This is easy to check. Let's take usbkbd.c.
The corresponding Kconfig (http://lxr.free-electrons.com/source/drivers/hid/usbhid/Kconfig#L50) says:
Say Y here only if you are absolutely sure that you don't want to use
the generic HID driver for your USB keyboard and prefer to use the
keyboard in its limited Boot Protocol mode instead.
This is almost certainly not what you want. This is mostly useful for
embedded applications or simple keyboards.
So it looks unlikely to be the keyboard driver we are looking for. Also check current kernel config for USB_KBD. The config can be found under /boot directory or by running zcat /proc/config.gz. If USB_KBD is not there, you're not using it. If usbkbd.c is built as module, then will be worth checking if it is actually loaded. Makefile (http://lxr.free-electrons.com/source/drivers/hid/usbhid/Makefile#L10) gives the target as usbkbd. We can check if it is loaded by grepping for it in output of lsmod.
In contrast, Kconfig (http://lxr.free-electrons.com/source/drivers/input/keyboard/Kconfig#L69) for atkbd.c seem much more likely:
Say Y here if you want to use a standard AT or PS/2 keyboard. Usually
you'll need this, unless you have a different type keyboard (USB, ADB
or other). This also works for AT and PS/2 keyboards connected over a
PS/2 to serial converter. If unsure, say Y.
Also check kernel config for KEYBOARD_ATKBD. If it is Y, you know it is being used. If it's M, check output of lsmod for atkbd.

What is proc and sysfs entries

I'd like to learn about proc and sysfs entries.
So far, what I have understood is that, proc entries are the values which is set to proc file system. I'm not sure whether I'm correct. Could anyone explain it in detail about its real need and where it is used? Please provide me links to know it better. Any kind of guidance is accepted.
The /proc filesystem is a special, software-created filesystem that is used by the kernel to export information to the world. Each file under /proc is tied to a kernel function that generates the file's "contents" on the fly when the file is read. We have already seen some of these files in action; /proc/modules, for example, always returns a list of the currently loaded modules.
/proc is heavily used in the Linux system. Many utilities on a modern Linux distribution, such as ps, top, and uptime, get their information from /proc. Some device drivers also export information via /proc, and yours can do so as well. The /proc filesystem is dynamic, so your module can add or remove entries at any time.
Fully featured /proc entries can be complicated beasts; among other things, they can be written to as well as read from. Most of the time, however, /proc entries are readonly files. This section concerns itself with the simple read-only case. Those who are interested in implementing something more complicated can look here for the basics; the kernel source may then be consulted for the full picture.
Before we continue, however, we should mention that adding files under /proc is discouraged. The /proc filesystem is seen by the kernel developers as a bit of an uncontrolled mess that has gone far beyond its original purpose (which was to provide information about the processes running in the system). The recommended way of making information available in new code is via sysfs. As suggested, working with sysfs requires an understanding of the Linux device model, however, and we do not
source - http://tjworld.net/books/ldd3/#UsingTheProcFilesystem
u can look at the ldd3 for more detailes.
it is often used as a tool for debuging the device drivers.
i am a newbie.
good luck.

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.

Linux: How to map a blockdevice to a USB-device?

if I plugin a USB memory stick, I see a new folder in /sys/bus/usb/devices ... thus a new USB-device.
Also I see a new folder in /sys/block ... thus a new block-device.
My question is: How can I get a waterproof mapping between those two devices? Means:
If I get a new device in /sys/bus/usb/devices, how can I programatically (f.i. by checking /sys/...) find out which block device is mapped/related to this usb-device and vice-versa?!
The information in /sys is organized in multiple ways (by driver, by bus, etc.), and there are many symbolic links to go from one hierarchy to another.
Case in point (example seen on kernel 2.6.26): starting from the block device in /sys/block/sdc, the symbolic link /sys/block/sdc/device points inside the per-device-type hierarchy. You can see that it's an USB device because the target of the link is something like
../../devices/pci0000:00/0000:00:1d.7/usb8/8-2/8-2:1.0/host9/target9:0:0/9:0:0:0
Conversely, USB devices are listed in /sys/bus/usb/devices, and we can see that 8-2:1.0 is a disk-like device because /sys/bus/usb/devices/8-2:1.0/driver links to usb-storage. To find out what the associated block device is, it seems we need to go down to the directory /sys/bus/usb/devices/8-2:1.0/host9/target9:0:0/9:0:0:0 which contains a symbolic link block:sdc whose target is /sys/block/sdc.
ADDED: Caution: the exact structure of /sys changes from kernel version to kernel version. For example, with kernel 2.6.32, /sys/block/sdc/device points directly into the /dev/bus/scsi without going through the USB hop.
A different approach is to call the udevadm info command. udevadm info -p /sys/block/sdc --query=… gives information on a device based on its /sys entry, while udevadm info -n sdc --query=… gives information on the device /dev/sdc.
The information includes bus information, for example udevadm info -p /sys/block/sdc --query=env shows
ID_BUS=usb
ID_PATH=pci-0000:00:1d.7-usb-0:2:1.0-scsi-0:0:0:0
The udev documentation may have more information of interest to you.
A final word of caution: there are all kinds of complex cases that may make whatever you do not so waterproof. How will your program deal with a single USB device that is an array of disks that are assigned multiple block devices? Conversely, how will your program deal with a RAID array assembled from multiple devices (perhaps some of them USB and some of them not)? Do you care about other removable media types such as Firewire and e-SATA? etc. You won't be able to predict all corner cases, so make sure to fail gracefully.
As far as I found out, it's possible to access udev information via "libudev" library. There's also a good sample on the net available: http://www.signal11.us/oss/udev/
I was able to modify it to read out all "/dev/sd*" devices and get their Vendor-ID, Product-ID as well as Serial number. I think this solution is kernel/linux distribution independant enough. But I still have to verify this.

Change arguments that start up with JFS driver on linux

I am more common with the QNX os and I could change the arguments for the ide driver on startup. I wanted to change the arguments that get started in a linux kernel for the jfs filesystem which mounts a flash card. I can't seem to find a good web source for this information but I am sure I am not "googling" it right.
What are the different options available for the jfs/ide driver and where do I change them for the current running driver?
Thank you and I apologize this isn't exactly programming but this site always produces great answers when I ask a programming question so I figure it might help here too.
ok, i finally found out it is defined in the /etc/fstab file. Now I just need to find out what options are available and best for a compact flash card.
Options for most filesystems are shown in the "mount" manpage.
The ata driver may also have various tunables. You can probably change these in real time with "hdparm".
Some options might be filesystem create time options, in which case mkfs will document them.
See the relevant man pages.
If you want to pass options to jfs, you need to pass them as part of kernel boot
line, which is specified in your grub.conf or lilo.conf file. You can find the supported
options in the Documentation/ directory of the kernel source, or the jfs source itself.
As for the recommended mount options, you need to look at the mount(8) man page.
I would recommend noatime,nodirtime at a mininum. The default is atime, which
causes the file inode to be updated everytime you look at a file.

Resources