Planet maemo: category "feed:3443cd3b09dca3afd960884d779d28f3"

Raul Herbster
Let's now show how to install a module into the just compiled Android kernel (see this post for more information)

For compiling the module, it's important that you use the same kernel source that is installed in your device. Otherwise, you cannot install the module.

a. Go to the code that contains an example of kernel module for Android (for instance, [your_code]/module/intercept);
b. Update the makefile to point to your kernel source code;
c. You need to set some env variables, including the cross-compiler. In this case, you can use the ones provided by the Android source, in the folder prebuilts:

   @desktop:$ export CROSS_COMPILE=[android_sdk]/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7/bin/arm-eabi-
   @desktop:$ export ARCH=arm
   @desktop:$ export PATH=$PATH:/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7/bin/
   @desktop:$ make
   (a kernel module file will be generated ([your_module].ko) and this is the one that we need to install in our rooted device)

d. Copy the .ko file to the device using the following command:

   @desktop:$ adb push [your_module].ko /data/local/tmp

e. Install the kernel module using the following commands:

   @desktop:$ adb shell
   @android:$ su
   @android:$ cd /data/local/tmp
   @android:$ insmod [your_module].ko

f. You might get some errors, such as "function not implemented". To check more details about what's wrong, you can check the log file by typing the following command.

   @android:$ dmesg

Raul Herbster
As you need to implement your solution into Android system, you end up learning a lot about the different Android layers (kernel, OS and applications) and how to integrate them. I decided to add the following list with some tips, as these small things took me some precious time to get it solved. The list will be often edited:

#01 - Make sure that you're flashing the device with the proper kernel image

This is what happened to me: I had previously built the kernel (something like two months before). Then, I had to build the OS image from scratch, that is, cleaning up the previous build (with make clobber). When I used the command make bootimage, including setting the variables properly, the output always had the wrong kernel image (not the one that I had previously built, but the existing one in the directory prebuilts). The build process won't take too old kernel images. Therefore, make sure that the compressed kernel image is always new. Even if you don't make any change on the kernel source, do make again to generate a new file.

Raul Herbster
This week, I tried to compile a simple NDK application and link it with the OpenSSL library. Most of libraries (including OpenSSL) are not supported by the NDK, what makes it a bit more complicated to use. So, in this post, I describe what I usually do to properly compile applications that need external libs.
Click to read 1630 more words
Categories: android
Raul Herbster
This week, I had to go through the process of Android OS/Kernel building/installation. And it was a lot much better and 6 months ago (maybe, because I built it for a device and not for the emulator?). I compiled the images in Ubuntu 12.04 and I used a Samsung Galaxy Nexus device (maguro with tuna as kernel). Therefore, I decided to summarize the steps that I took. This mini-tutorial is a lot shorter and simpler (and really works!!).
Click to read 1448 more words
Categories: android
Raul Herbster

Building/Running Android Goldfish kernel

2013-08-26 14:21 UTC  by  Raul Herbster
Among the tasks for build an Android kernel development, building the Android Goldfish kernel is the easiest :-) (I mean, no compiling errors...)

First, you need to have access to the cross-compiling tools. The Android source code provides them in folder /prebuilt/linux-x86/toolchain/. 


1. Set the path to include the pre-build toolchain
   # export PATH=/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/:$PATH
2. Set the Kernel config file. In this case, we are compiling for the ARM emulator (armv7).
   # make ARCH=arm goldfish_armv7_defconfig
3. Run make
   # CROSS_COMPILE=/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- ARCH=arm make
   # export ANDROID_PRODUCT_OUT=/out/target/product/generic/
5. Run the emulator
   # /out/host/linux-x86/bin/emulator-arm -system /out/target/product/generic/system.img -kernel /goldfish/arch/arm/boot/zImage -data /out/target/product/generic/userdata.img -ramdisk /out/target/product/generic/ramdisk.img -skindir /sdk/emulator/skins/ -skin HVGA -verbose -show-kernel


  • The option CONFIG_MODULES is NOT enabled by default. If you want to insert modules into the kernel, make sure to set CONFIG_MODULES;
  • Android emulator does NOT work with Kernels > 2.6.X So, make sure to use the proper Kernel. For devices, any support Kernel will work.

Categories: android
Raul Herbster

Android (Goldfish) kernel development

2013-08-26 14:02 UTC  by  Raul Herbster
Finally, back to this :-)

Lately, I have being developing a new project which basically needs some kernel changes on Android Goldfish kernel. Initially, I thought that this would be something like "traditional" kernel development, but NOT. Android kernel is, of course, a Linux kernel but it has some peculiarities that impact on the development phase.

[NOTE] I'd rather provide a link to the source that I used than replicating the same information.

So, I split my experience into the following topics:
  1. Building Android ICS
  2. Building/Running Android Goldfish kernel 
  3. Creating a Goldfish kernel module
  4. Adding new syscalls into the Goldfish kernel
Categories: android
Raul Herbster

Building Android ICS

2013-08-26 14:02 UTC  by  Raul Herbster

To compile ICS (and probably any new version of Android platform >= 4.0), you
might have some problems with the compilation tools.
Click to read 1430 more words
Categories: android
Raul Herbster


2013-01-25 00:25 UTC  by  Raul Herbster
My life has changed upside down recently: I have been accepted to Saarland University Graduate School and I will move to Germany soon. I will try to keep this updated as possible.
Raul Herbster
Well, a short break on continuous integration posts!
Click to read 1528 more words
Categories: arm
Raul Herbster
Continuous Integration is such a great idea: it works as a trainee that constantly downloads/builds/tests/deploys you application and notifies you whether something goes wrong or nice. I really do believe that (of course, besides several other advantages) it improves the project overall quality and also helps you to keep the application ready to be reviewed by a stakeholder.

If you are still skeptical about it, please take a look that this marvelous post here [Martin Fowler] .

Let´s discuss how you can set up a environment for a more complex project. So, unfortunately, this is tutorial for beginners (for basic/how-to-install-and-run instructions, check it on internet).


The system consists of one server located in a external environment (for example, AWS services) and several mobile clients (iOS, Android and QT clients). Basically, the mobile applications fetch content/data from the server.

We need to constantly build/deploy the server and build all mobile clients. One very interesting point in this scenario is the amount of platforms: iOS (to build iOS client), Linux (to build Android/QT client - I´d rather use Linux for Android projects) and Windows (to build the server).

Besides svn checking-out + building + testing + deployment, we will also use QA solutions, such as Sonar and some static analysis tools for different platforms.

We will use Jenkins as CI server.

Proposed design

As I said, the system consists of several components: mobile clients (iOS, Qt and Android) and also servers. In this case, I´d rather use master-slave approach. You can create one slave for each mobile platform and also another one for for servers. To the given example, the solution is defined as it follows:

You might ask me why this is too complicated! But believe on me. If you have complex systems to build, this approach works a lot better: it´s easier to organize and to maintain, and each component on its own environment. In my next post, I describe how we set up all of this :-)
Categories: android
Raul Herbster


2012-10-26 23:20 UTC  by  Raul Herbster
After a loooong break, I am back to this. I have to confess that I had had several new/cool stuff during this pause: new projects, mind-blowing findings, exciting/stressful experiences, lovely/irritating people. And all of this had consumed a lot of my free time. I am not saying that I hadn´t had time at all: I had done some new/different things with such slots of time than only writing about technical stuff.

Well, but anyway, let´s keep track of new stuff. The main reason to start blogging again was the simply fact that I am not used to describe all solutions for tricky problems in general: how to cross-compile certain applications for ARM devices, how to set up a smart CI environment, and so forth. I swear I have tried it really hard, but my evil side always tells to myself: "if you need it some other day, you will remember it". So, this is also a kind of "Raul´s Recipes Book".

I am really convinced that it will work :-)

As part of my next posts, I will describe a bit more about how lovely is a CI environment for a relative huge project (of course, how you can set up all of this and put the pieces together). Specially, when it has such different clients, such as iOS, Android and QT applications.
Raul Herbster

DBus - How to pass dict as parameter

2010-11-18 14:02 UTC  by  Raul Herbster
This tutorial is designed for those ones that need DBus but suffer a lot to find documentation even about simple things, such as how to pass a dictionary as parameter.

Initially, I had to invoke a Bluez method that needs a dictionary as parameter. But how could I do it? It not easy at all to find a detailed documentation about it and I had to look for a solution at BlueZ source code.

In this case, I'm using the newest BlueZ Health API (support for HDP/MCAP). The following piece of code shows

static char *start_health_session(DBusConnection *conn)

DBusMessage *msg, *reply;
DBusMessageIter args;
DBusError err;
const char *reply_path;
char *path;

msg = dbus_message_new_method_call("org.bluez",

if (!msg) {
printf(" network:dbus Can't allocate new method call\n");
return NULL;

// append arguments

dbus_message_iter_init_append(msg, &args);

if ( !iter_append_dictionary(&args, DATA_TYPE_VALUE,
printf(" network:dbus Can't append parameters\n");
return NULL;



A DBus dict type needs a message iterator, which is properly initialised before it is used.

Once the message iterator is properly created, let's open it and add tuples to it.

static int iter_append_dictionary(DBusMessageIter *iter,
dbus_uint16_t dataType,
const char *role,
const char *description,
const char *channelType)
DBusMessageIter dict;

dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,

dict_append_entry(&dict, "DataType", DBUS_TYPE_UINT16, &dataType);

dict_append_entry(&dict, "Role", DBUS_TYPE_STRING, &role);

dict_append_entry(&dict, "Description", DBUS_TYPE_STRING, &description);

dict_append_entry(&dict, "ChannelType", DBUS_TYPE_STRING, &channelType);

dbus_message_iter_close_container(iter, &dict);

At first, you have to open the container and specify the data type of each tuple. In this case, the dictionary consists of tuples , , , and . Once the value data type for each tuple varies (uint16 or string), we declare it as a variant. Therefore, the dictionary data type definition is:


Finally, you simply add the basic data type to message iterator (the dictionary itself).

static void append_variant(DBusMessageIter *iter, int type, void *val)
DBusMessageIter value;
char sig[2] = { type, '\0' };

dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, sig, &value);

dbus_message_iter_append_basic(&value, type, val);

dbus_message_iter_close_container(iter, &value);

static void dict_append_entry(DBusMessageIter *dict,
const char *key, int type, void *val)
DBusMessageIter entry;

if (type == DBUS_TYPE_STRING) {
const char *str = *((const char **) val);
if (str == NULL)

dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
NULL, &entry);

dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);

append_variant(&entry, type, val);

dbus_message_iter_close_container(dict, &entry);

Categories: dbus