Linux – Kernel hacking methodology – how to find out where to hack the linux kernel

cdriverslinuxlinux-kernel

I have a throw-away cheap laptop I'd like to twiddle around, a Thinkpad SL 500.

What bothers me are two leds, the one for wireless connectivity, and the one for hibernation, which don't light up at all, although they're functional, I've tried it on windows.

So I would like to write a kernel driver for them, nothing big, it just looks like a good idea to play around with the kernel.

My question is what methodology should I follow systematically to find out what devices are responsible for those leds (in general, not necessarily specific to my hardware), and what drivers are responsible for the other two leds that work, bluetooth and the battery indicator?

And when I say methodology, I really mean the methodology, step by step, with reasons for each step, like in the answer I've gave to someone else over here: What does && mean in void *p = &&abc;

I am profficient at fgrepping through big code repositories, using static code analysers & co, but I think my lack of hardware knowledge hinders me on this problem.

PS: I'm using ArchLinux, so almost the latest kernel version.

Best Answer

I think my lack of hardware knowledge hinders me on this problem.

Then let's start with the basics. Indicator LEDs can be controlled several ways:

  • The LED is controlled directly by a peripheral chip/device. In this situation, the CPU and the kernel driver would have no control over the LED. This is typically the case for the "activity" and "link speed" LEDs on an Ethernet RJ-45 jack; these LEDs would be under direct/exclusive control of the Ethernet PHY device.

  • The LED is controlled by a GPIO (General Purpose Input/Output) pin of the CPU or SoC.

  • The LED is an output of external logic (e.g. an FPGA chip).

  • The LED is an output on a peripheral chip.

The last three situations may not be distinguishable in the source code. One bit in a port or device register will turn the LED on or off. Inspect the header file for what the other bits in the register will control. The register will be read/written using either I/O instructions or memory fetch/store instructions depending on the processor architecture.

Note that the LED is often a current sink and tied to logic high voltage, so the LED is turned on by grounding the pin by writing a 0 bit value. Conversely the LED is typically turned off by writing a 1 bit value. Since only one bit of the register is being changed, a read of the whole register is typically required prior to the bit modification. The register itself may be a critical region, which will necessitate the acquisition (& release) of a mutex or spin-lock to protect the entire operation.

Source Code Inspection

If the device drivers are proprietary, then you're screwed. Otherwise you should be able to obtain the source code. Your distro should make its source code available. There are online viewers such as this Linux kernel tree with built-in cross-reference hyperlinks. If the drivers are not in the mainline kernel source tree, then you should ask the hardware manufacturer to provide the source code per terms of the GPL.

You have mentioned four indicators:

  • wireless connectivity
  • hibernation
  • bluetooth connectivity
  • battery

Obtain the output of the lsmod command, which will list the runtime modules appended to the kernel. From the list of modules, you need to determine which drivers correspond to the functionality of these LEDs, e.g. wireless networking, power etc. Assuming that this ThinkPad has an Intel wireless controller chip, then you would need to look in the drivers/net/wireless/iwlwifi directory. Inspect the Kconfig and Makefile files in that driver directory for the correlations between the actual HW device name, the configuration symbols, the .ko module(s) built and the corresponding source code.

Review the driver source code for manipulation of the indicator LED. If the operation is not commented, then you'll have to look for a bit operation, or a macro, or a procedure call. There are many ways to organize this code depending on the modularity of the code, or if OOP techniques were employed and these LED operations are encapsulated in procedures in some other driver. Beware of text (executable code) in macros (i.e. #define) and in header files. That is, reviewing just the .c files would be a mistake. Also beware that some device code may be under arch/xxx/platform or arch/xxx/machine, especially for embedded single-board computers.

Related Question