Search code examples
androidmakefilekerneldevice-driver

migrating a linux driver to Android


I'm porting a 3G modem written for Linux for laptops to an embedded android (Gingerbread) device with an ARM processor. I already got the device driver compiled (C code) as a module (.ko file) and installed. I see it when I boot the kernel and it runs well. It hooks up to the USB port as intended. It's happy ready to be talked to.

The next required piece is the "connection manager" written in C++. This is where I have a problem. This doesn't run in Kernel space but it is not a regular Android application with a user interface. This is a "task" running in background that should be started from the "init.rc" file at boot time. The makefile provided with the source code is good to set the dependencies but it is useless as far as the platform I want to target. I'm using the toolchain provided with the Android source code "arm-eabi-*" (runs off of a Ubuntu machine) that I used to compile Android and the kernel. I got lots of compile errors primary because it uses the standard "libc" libraries which doesn't exist in Android. I replaced it by the "bionic libc" which is a light weight subset version of linux libc for android. On top of it, it looks for "crt0.o" which is the start-up code a statically linked program in a linux environment(and several other OS). In Android it is dynamically linked at run time, therefor uses something else than crt0.o.

There is tons of information on Android app programming on the web but, very little on that kind of low level stuff. If anybody has a working makefile for building that kind of C++ code to run as a background task under Android ARM, I would very appreciate to have a look at it or if there is any information that could help me find a way to do that. Or if anyone has done something like that could give me some clues on how to achieve this.


Solution

  • Almost a year later, but here is a makefile that will compile a simple native app:

    NDK_USR_PATH := $(NDK_USR)
    
    C_FILES := $(wildcard *.c) $(wildcard *.cpp)
    O_FILES := $(patsubst %.cpp,%.o,$(C_FILES))
    O_FILES := $(patsubst %.c,%.o,$(C_FILES))
    
    out: $(O_FILES)
            @arm-eabi-gcc -o $@ $< -Bdynamic -Wl,--gc-section -Wl,-z,nocopyreloc -Wl,--no-undefined -Wl,--dynamic-linker=/system/bin/linker -Wl,-rpath-link=$(NDK_USR_PATH)/lib -nostdlib $(NDK_USR_PATH)/lib/crtend_android.o $(NDK_USR_PATH)/lib/crtbegin_dynamic.o -L$(NDK_USR_PATH)/lib -lc
    
    %.o: %.c 
            @arm-eabi-gcc -o $@ $< -c -I$(NDK_USR_PATH)/include -fno-short-enums
    
    clean:
            @rm -f *.o
            @rm -f out
    

    It compiles any .c files in the same directory into an app named "out". It requires the environment variable NDK_USR to point to the ndk directory "ndk/android-ndk-r7/platforms/android-14/arch-arm/usr/".

    This should dynamically link to the bionic libc, and should enable android driver development.

    Be careful when copying and pasting the above makefile. Make is very specific about tab characters.