Kernel programming

So, you want to do something that requires some kernel changes. The most common way of adding functionality to the kernel is by writing a device driver.

Resources
If you've never written a linux device driver before, then the Linux Device Drivers, 3rd edition is a MUST READ. It is also available in PDF form.

Using kernel modules allows device drivers to be added to the kernel, often without requiring that the kernel be rebuilt. Some resources for learning how to write a kernel module is the Linux Loadable Kernel Module HOWTO (also available in PDF) and The Linux Kernel Module Programming Guide (also available in PDF).

The Linux Documentation Project contains numerous documents on all manners of linux.

Sample char driver
Most drivers for interfacing with simple hardware can be implemented using a character driver. A sample character driver is included below.

The source files and precompiled binaries can be found on the following tarballs:
 * char-driver-2.6.17.tar.gz
 * char-driver-2.6.18.tar.gz - For 2.6.18 prior to SVN revision 1185
 * char-driver-2.6.18-1185.tar.gz - For SVN revisions 1185 and newer
 * char-driver-2.6.21.tar.gz - For kernels 2.6.21 and newer

This particular driver was intended to be installed as a loadable module. To use, copy the char-driver.ko, and sample files to the gumstix. The sample driver allocates major numbers dynamically and registers a class, so that udev should automatically create the /dev/sample device node.

Execute the following command to load the module: insmod char-driver.ko

This driver has a number of controls which can be manipulated using the /proc filesystem. For this driver, the following can be found in the /proc/sys/sample/ directory:

When the driver is opened, it will install in interrupt handler for the indicated GPIO pin. Whenever a falling edge is detected, it will queue up an event with the timestamp (current jiffy count). This will in turn wakeup any user mode process waiting to read data from the queue. Finally, there is an ioctl to retrieve the kernel's notion of HZ. On the gumstix the kernel HZ and user HZ are both set to 100, but on other platforms this might not be the case.

Monitoring multiple GPIO pins
The GPIO_event page describes another kernel driver which is capable of monitoring multiple GPIO lines.