Skip to content

Build C/C++ Executables for android using NDK

Hello everyone,

I was wandering if I can compile C binary that runs on android platform, So a long time ago I found a method (without using ndk), with

     arm-none-linux-gnueabi-gcc -static test.c -o test

Using above command, we can compile a C file named test.c as a static binary. Yes, with this method we can only compile static binaries. But I thought hey.. that is not the most convenient way to compile means I don’t want to compile my binary every time static.

So, I found an alternative (and proper) way to build C/C++ executable using Android NDK. Let’s take an example to see how it works.

Prerequisites:

1. Linux Host (not yet tried on windows)

2. Android NDK on host machine

Let’s create a simple hello world C program in file test.c

#include <stdio.h>
#include <stdlib.h>
int main()
{
     printf("Hello World\n");
     return 0;
}

So, above program will just print “Hello World” on standard output.

Now, to compile it with NDK, we need a Android.mk. the Android.mk will look like this.

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS) 
# give module name
LOCAL_MODULE    := hello_world  
# list your C files to compile
LOCAL_SRC_FILES := test.c
# this option will build executables instead of building library for android application.
include $(BUILD_EXECUTABLE)

The NDK system is only able to compile in android project hierarchy.

So, we need to create a directory structure like this

hello_world
     |
     `-- jni
     `-- libs

Now, place test.c and Android.mk file in jni directory.

Follow these steps on command line:

     $ mkdir  ~/hello_world/
     $ mkdir ~/hello_world/jni
     $ mkdir ~/hello_world/libs
     $ cd ~/hello_world/jni/
     $ gedit test.c
               # create your C code in file, save and exit.
     $ gedit Android.mk
               # write Android.mk contents, save and exit.
     $ export PATH=$PATH:<path/to/ndk>/
     $ ndk-build

By executing “ndk-build”, ndk will compile our test.c (not static) and puts the binary in hello_world/libs/armeabi/

Advantages of using NDK:

1. We don’t have to compile binaries static, so size of binary will be reduced.

2. We can use android C/C++ libraries like liblog to print output in logcat from C.

Let me know if you have any doubts on this in comments.

Linux Kernel

Hello guys,

Linux kernel is monolithic kernel. hmmm.. but wait I don’t know what a kernel is. Well let’s have a ride in kernel coaster. ;)

What is Kernel?

In simple words, a kernel is an interface between hardware and OS. It takes commands from OS and make hardware act upon and takes data from hardware and gives it to OS. It also provides inter process communication.

Types of Kernel

There are majorly three types of kernel

  1. microkernel
  2. monolithic kernel
  3. hybrid kernel

each kernel type has its advantage and disadvantage. Let us talk briefly about each type.

Microkernel

Microkernel is kernel which only does main handling i.e. CPU, memory and IPC. Everything else is managed in user mode. Now there are two modes in a system.  1) user mode and 2) supervisor mode. Everything running in OS is in user mode and everything running from kernel is in supervisor mode. As the name says, In supervisor mode process has more permissions to do stuff than user mode.

So, In microkernel only few things are running in supervisor mode and rest things have to run in user mode.Now, This has few advantages and few disadvantage.

Advantages:

With this, kernel has small install footprint as well as memory footprint. Another advantage is kernel will be more portable because it is doing main handling it can run on almost every where. the rest things can be different which are running in user mode. By this we get more security because less processes are running in supervisor mode so all rest processes does not have full rights to do things.

Disadvantages:

Now, In monolithic kernel, most of the process will run in user mode, so each process has to wait in queue to get information and also it can not do inter process communication without waiting. Hardware may run slower because drivers are running in user mode.

Monolithic Kernel:

Monolithic kernels are opposite of microkernels. They include basic handling of CPU, memory and IPC as well as it also includes device drivers, file system management, system server calls. Monolithic kernel tends to be better and multitasking because all process are running in the same mode. So waiting time of ipc and to get information can be reduced. Now this however can cause problem because many processes are running in supervisor mode and defect in one process can make whole system down. Monolithic kernel has following advantages and disadvantages:

Advantages:

In monolithic kernel, processes has more direct access to hardware. Processes has easiness to inter communication. Processes reacts faster because they don’t have to wait in queues.

Disadvantages:

Since monolithic kernel includes more things, its install/memory footprint is increased. It is less secure because many processes runs in supervisor mode.

Hybrid Kernels:

Hybrid Kernels are combination of microkernel and monolithic kernel. In hybrid kernel user can choose what needs to be run in user mode and what needs to be run in supervisor mode. So it has advantages of both types of kernel as well as disadvantages of both kernels. Windows and OS X kernels are Hybrid kernels.

Linux Kernel

Ffffff…Now we know what is a kernel, so let’s little bit about Linux kernel.

You can find Linux kernel in your /boot directory in Ubuntu. There may be different names for kernel. each type of name denotes some special about that kernel and those are,

vmlinux – normal kernel image, In early days it was unix. after that it is changed to linux and then virtual memory concept came in picture so it is called as vmlinux.

vmlinuz – zlib compressed kernel image.

zImage – compressed + virtual memory support kernel image

bzImage – zImage compressed to the max

uImage – kernel image for U-boot i.e. very popular boot loader for ARM based platform.

There are different kernel version. Version number rules are:

linux-version-image

Linux kernel has one more important thing, that is its capability to insert / remove modules. I will talk about Linux kernel modules in later posts may be.

I guess, That is enough knowledge to start exploring in Linux kernel.

Enjoy.

Build your own Linux Kernel

Download a mainline stable kernel from the kernel.org

You can download the latest stable kernel from the website.
Now, please note that I am doing this process on Ubuntu 10.04.
After the download is finished. extract the package.
$tar -xvf  linux-3.6.7.tar.bz2
$cd  linux-3.6.7

Now you have to configure the kernel as per your system. (So kernel can actually work on it…). If you don’t know how to configure (like me ;) ) then you can find the existing configuration from your current system.

You can find them in /boot directory. In my case file name was “config-2.6.32-21-generic”. So you can directly copy that configuration.
$cat /boot/config-2.6.32-21-generic > .config
Now with old configuration loaded, we also need to enable few more configuration that are added newly. So for that execute,
$make oldconfig
Just hit enter on every selection, so it will take the default. So now your kernel is ready with configurations.
Compile the kernel using,
$make -j2 && sudo make modules_install
Place the compiled kernel in boot directory
$sudo cp arch/i386/boot/bzImage /boot/vmlinuz-3.6.7
Now we need to update the grub (the boot loader) so it can detect and boot this kernel.
$sudo update-grub2
by running above command, you will get an auto generated file /boot/grub/grub.cfg
In that find this section,
menuentry 'Ubuntu, with Linux 3.6.7' --class ubuntu --class gnu-linux --class gnu --class os {
     recordfail
     insmod ext2
     set root='(hd0,1)'
     search --no-floppy --fs-uuid --set 42d5cc2e-4a0c-4312-91c2-e9ef9d0aecb7
     linux     /boot/vmlinuz-3.6.7 root=/dev/sda1 ro   quiet splash
}
menuentry 'Ubuntu, with Linux 3.6.7 (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os {
     recordfail
     insmod ext2
     set root='(hd0,1)'
     search --no-floppy --fs-uuid --set 42d5cc2e-4a0c-4312-91c2-e9ef9d0aecb7
     echo     'Loading Linux 3.6.7 ...'
     linux     /boot/vmlinuz-3.6.7 root=/dev/sda1 ro single 
     echo     'Loading initial ramdisk ...'
}
Now, In this section add necessary changes in this section according to other existing menuentry
Now try to boot your new Linux kernel. I hope you get it working.
Well, this part of process just a beginning process, you also need to do some more configuration and stuff (If this doesn’t work of-course).
But, By this process you can get idea what to do after that configuration and stuff.
Hope you enjoyed the article.
Thanks.

Install Java6 on Ubuntu

Hi all,

Let us install sun-java6-jdk on ubuntu.

On Ubuntu 10.04:

Now This are the standard method to install it.

Open your terminal by Ctrl+Alt+T

$sudo add-apt-repository "deb http://archive.canonical.com/ lucid partner"
$sudo apt-get update
$sudo apt-get install sun-java6-jdk

Now I guess You will encounter with this problem in last step.

Package sun-java6-jdk is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
E: Package sun-java6-jdk has no installation candidate

Now the solution to this is:

$sudo add-apt-repository ppa:ferramroberto/java
$sudo apt-get update
$sudo apt-get install sun-java6-jdk

And finally you have installed sun java6 on your ubuntu 10.04

 

On Ubuntu 12.04:

To install sun java6 on ubuntu 12.04 follow this steps:

Open your terminal by Ctrl+Alt+T

Enter following commands and you will get sun java6 installed on your system.

$wget https://github.com/flexiondotorg/oab-java6/raw/0.2.6/oab-java.sh -O oab-java.sh

This will download the script to install sun java.

After that provide executable permission to that script.

$chmod +x oab-java.sh

And after that execute the script

$sudo ./oab-java.sh

I don’t know who is the author of this script, but hats off to that guy, that made our work so easy to install java.

Well, Now a little bit of patience, so that this script downloads some packages required.

After that execute installation commands:

$sudo apt-get install sun-java6-jre sun-java6-jdk sun-java6-plugin sun-java6-fonts

Enjoy…

How ARM based device starts?

Hi guys…have you ever wandered how the embedded dev kit starts up when we plug the power supply?.. well let’s discuss about it.

Now, when we plug in the power to the device, the cpu code initializes and looks for the boot select configured. Now this boot select might be some switch or jumper or software auto boot select. There are many boot options available on device like device can get booted from flash memory or memory card or serial flash or from USB. Based on the device hardware we can choose one of them.

Now let us understand the key components who helps an embedded device to be up and running.
1. Primary boot loader
2. Secondary boot loader
3. Kernel image
4. File system

The cpu code will execute the primary boot loader and also initializes required peripherals to do that like flash chip or mmc interface etc.
The duty of primary boot loader is to load secondary boot loader and initialize required hardware for that. (Just like passing the duty)
X-loader is a popular primary boot loader for ARM. Primary boot loader is also referred as bootstrap mostly.

Now, the job of secondary boot loader is to provide configurable environment to user so that he/she can load OS kernel from where ever he wants or however he wants. For example if I want to load kernel from network, I can do it from this secondary boot loader. Same as if I want to allocate certain amount of memory I can do it from here.
U-boot is a popular secondary boot loader for ARM devices. We will discuss more about this configuration stuff later(in my other post may be).

Now let us assume that u-boot (now i will refer secondary boot loader as u-boot) is configured properly. So it will read the kernel image and pass the control of hardware to the kernel. Kernel will also get some configurations from u-boot. Based on that it will initializes hardware and required device drivers and tries to mount the file system. After mounting the file system successfully it will continue normal Linux init stuff and after that your device is up and running.

So, simply the procedure is,

x-loader –> U-boot –> kernel OS

Let’s take an example scenario which will help you understand more better,

I have one development kit named Tsunamipack-XL. It supports boot from NAND flash or MMC or USB stick.

I have my all system is NAND memory. So when I will plug in the power supply to that kit the CPU will first look for bootfiles on mmc card. Here bootfiles means x-loader, U-boot and Kernel Image. If it doesn’t find them on MMC card it will go to the first memory location of NAND memory and reads x-loader from there and executes it assuming x-loader is there on that location. After that x-loader will read the U-boot from next NAND memory locations and passes control to U-boot. Now U-boot will provide user a console based interface to configure the system. So I will configure my system such a way that it will read the kernel image from NAND memory, provide the file system partition location on NAND memory with some other kernel options and executes the kernel image. Rest of the procedure is same as I explained earlier.

If you noticed, here from the u-boot I can change the kernel image location and tell it to read it from mmc card or from network. so that is the advantage of u-boot. There is a lot of things more that u-boot can do.

So that was the brief info about how ARM based device starts.

I will discuss Linux init process and other concepts is my other post. So stay in touch for that.

Usage of TFTP server to transfer files

To Download any file from TFTP server.
use this command:
#tftp -g -r <filename> <ip-addr>
To push/upload anyfile from device to host:
use this command on device
#tftp -p -r <filename> <ip-addr>
ACCESS VIOLATION ERROR:
when we get error like this on some device while pushing file to host.We need to create a file with the same name of file we want to transfer.Use touch command to create files
$cd /tftpboot
$touch a.out
$chmod 777 a.out
Now at device side transfer the file using tftp
#tftp -p -r a.out <ip-addr>

TFTP server setup

While working with any embedded development kit, Using TFTP to transfer files between Host PC and target device is a good solution.

Read more about tftp on this link

Basically, In this method we will create a TFTP server on Host PC which will be a kind of the directory in Host PC. The files in that directory will be available to all who supports TFTP and can do file transfers also.

One of the key usage of this TFTP server is while developing kernel images we should not flash the kernel images all the time on embedded dev kit’s flash memory. because it will reduce the flash memory’s life. for more information you can refer to this wiki link.

So, that was some briefing about TFTP and now let us see the steps to set up that server.

I am using Ubuntu 12.04.

First Install following packages:

$sudo apt-get install xinetd tftpd tftp
Now create file /etc/xinetd.d/tftp

$gedit /etc/xinetd.d/tftp

Write following in the file tftp

service tftp
{
protocol = udp
port = 69
socket_type = dgram
wait = yes
user = nobody
server = /usr/sbin/in.tftpd
server_args = /tftpboot -s
disable = no
}

Now let us create tftpboot directory where all the files of tftp server will be stored

$sudo mkdir /tftpboot

$sudo chmod -R 777 /tftpboot

$sudo chown -R nobody /tftpboot

Now, Restart the xinet tftpd so that our tftp server gets ready to work.

$sudo /etc/init.d/xinetd stop

$sudo /etc/init.d/xinetd start

And That’s it. TFTP server is ready now.

Enjoy.

Thanks.

Follow

Get every new post delivered to your Inbox.