Jun 16, 2015

Android and Linux Hello World Driver

Adventuring in the Linux and Android driver world ? here you can see how to do a simple hello world driver for Linux/Android, using an LG Optimus 4x phone as target and Ubuntu 14.04 as host.

The target system is an Optimus 4x model P880 with a Nvidia ARM SoC running some Linux version, and as a mobile phone, it has small RAM and space available, so we need do all the job in another place, like a PC / x86 computer, in this scenario the PC is called host.

What is needed?

The host CPU architecture (PC / x86) is different from the target architecture (ARM), so we need a cross-compiler toolchain, that includes the compiler, linker, assembler and all the tools needed to generate the ARM architecture instructions, instead of PC. After this, we need compile the driver using the same Linux kernel source of the target.

The Linux Kernel and ARM Toolchain

The trick part and most problematic is the kernel source of your device, if you are using some custom ROM like the cyanogenmod, use the respective provided sources. If you use the wrong kernel source files, without the manufacturer patches for example, your driver will not work, so make sure to find the proper kernel source before proceed. In my case I couldn't find the sources because it's the original LG ROM.

So let's start discovering the target Linux kernel version and get its configuration file, for this you need a SSH server app running in the phone and a SSH client in the host. I'm using the Linux SSH client and SSHDroid app as server for Android, then type:

uname -r
3.1.10-g0cf45eb

As we can see, the kernel version is "3.1.10-g0cf45eb", so download the kernel sources for version 3.1.10 from kernel.org and extract it in the host machine. Then copy the kernel configuration file from "/proc/config.gz" to the kernel folder and extract the single file inside of it as ".config". Now the kernel sources folder has the vanilla kernel 3.1.10 version with the same configurations of the target. But we can't forget about the "-g0cf45eb" in the kernel version, so edit the Makefile:

EXTRAVERSION = -g0cf45eb

And install the ARM toolchain:

apt-get install g++-arm-linux-gnueabi

Now we are ready to cross-compile the driver for ARM !

Driver

Create a 'hello_driver' folder above the kernel source folder with a file named "driver.c":

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>

MODULE_LICENSE("Dual BSD/GPL");

static int hello_init(void) {
  printk("Hello world!\n");
  return 0;
}

static void hello_exit(void) {
  printk("Hello exit!\n");
}

module_init(hello_init);
module_exit(hello_exit);

The Makefile:

obj-m := driver.o

And from the kernel source folder, type:
make modules ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
make modules M=../hello_driver ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-

Now go back to the driver folder and you should have the 'driver.ko':
modinfo driver.ko
filename:       driver.ko
license:        Dual BSD/GPL
depends:       
vermagic:       3.1.10-g0cf45eb SMP preempt mod_unload ARMv7

That's all! copy the driver to the phone and test, it will print messages in the kernel log file, use the command 'dmesg' to see them!

0 comentários :

Post a Comment