Archive for category Android

MTD-Utils for Android

git clone git://git.infradead.org/mtd-utils.git mtd-utils

[to do]

Advertisements

Leave a comment

Install Android build requirements


Installing the JDK
The Sun JDK is no longer in Ubuntu's main package repository. In order to download it, you need to add the appropriate repository and indicate to the system which JDK should be used.

Java 6: for Gingerbread and newer

$ sudo add-apt-repository "deb http://archive.canonical.com/ lucid partner"
$ sudo add-apt-repository "deb-src http://archive.canonical.com/ubuntu lucid partner"
$ sudo apt-get update
$ sudo apt-get install sun-java6-jdk
Java 5: for Froyo and older

$ sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu dapper main multiverse"
$ sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu dapper-updates main multiverse"
$ sudo apt-get update
$ sudo apt-get install sun-java5-jdk
Installing required packages
To set up your development environment, install the following required packages:

$ sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev libc6-dev
lib32ncurses5-dev ia32-libs x11proto-core-dev libx11-dev lib32readline5-dev lib32z-dev

Ubuntu 11.10

sudo add-apt-repository "deb http://us.archive.ubuntu.com/ubuntu/ hardy multiverse"
sudo add-apt-repository "deb http://us.archive.ubuntu.com/ubuntu/ hardy-updates multiverse"
sudo apt-get update
sudo apt-get install sun-java5-jdk

sudo update-java-alternatives -s java-1.5.0-sun

java -version

1 Comment

Compiling Busybox for ARM and Android

# Download the source from git

hamilton@saygon:/tmp$ git clone git://busybox.net/busybox.git

hamilton@saygon:/tmp$ cd busybox/

#Export ARCH and  CROSS_COMPILE (check your toolchain)

export ARCH=arm
export CROSS_COMPILE=/opt/gcc-4.1.2-glibc-2.5-nptl-3/arm-none-linux-gnueabi/bin/arm-none-linux-gnueabi-

#Enter the configuration interface

hamilton@saygon:/tmp/busybox$ make menuconfig

#and follow these procedures

$ Busybox Settings --> Build Options --> Build Busybox as a static binary (no shared libs)  -  Enable this option by pressing "Y"
$ Busybox Settings --> Build Options --> Cross compiler prefix  -  Set this option equal to "arm-none-linux-gnueabi-"
$ Busybox Settings --> Installation Options --> Don't use /usr  -  Enable this option by pressing "Y"
$ Linux Module Utilities --> () Default directory containing modules - Set this option to nothing
$ Linux Module Utilities --> () Default name of modules.dep - Set this option to nothing

#Select desired packages and save your configuration and run make, after compilation you will have a busybox binary

hamilton@saygon:/tmp/busybox$ file busybox
busybox: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, for GNU/Linux 2.6.14, stripped

#Upload the file to your adb device and install busybox using ./busybox –install -s

#You can find more tips here http://omapzoom.org/wiki/Android_Installing_Busybox_Command_Line_Tools

2 Comments

Porting WiFi drivers to Android

For mini-box.com picoPC we want to support several USB and miniPCI WiFi dongles, this guide provides a step by step explanation of what’s involved in adding a new wifi driver and making wifi work in a custom Android build  (this guide was written for android 2.1 but should be applicable to previous android releases and hopefully future releases).
Contents
0. Understand how Android WiFi works.
1. Enable building of wpa_supplicant in your BoardConfig.mk
2. (Optional) Enable debug for wpa_supplicant.
3. Provide a proper wpa_supplicant.conf for your device
4. Have the correct paths and permissions created from init.rc
5. Make sure your wpa_supplicant and dhcpcd (optional) are starting from init.rc
6. Provide your driver either as a module or built in kernel and proper kernel support for it and modify Android source code accordingly.
7. Provide a firmware if your module needs it.
8. Make your driver work with Android custom wpa_supplicant commands and SIOCSIWPRIV ioctl

Now onto details.

0. Understand how Android WiFi works.
Android uses a modified wpa_supplicant ( external/wpa_supplicant ) daemon for wifi support which is controlled through a socket by hardware/libhardware_legacy/wifi/wifi.c (WiFiHW) that gets controlled from Android UI through android.net.wifi package from frameworks/base/wifi/java/android/net/wifi/ and it’s corresponding jni implementation in frameworks/base/core/jni/android_net_wifi_Wifi.cpp Higher level network management is done in frameworks/base/core/java/android/net

1. Enable building of wpa_supplicant in your BoardConfig.mk
This is by simply adding: BOARD_WPA_SUPPLICANT_DRIVER := WEXT to your BoardConfig.mk . This will set  WPA_BUILD_SUPPLICANT to true in external/wpa_supplicant/Android.mk enabling building of driver_wext.c
If you have a custom wpa_supplicant driver (like madwifi or my custom android private commands emulation – see last paragraph) you can replace WEXT with AWEXT or your driver name (MADWIFI, PRISM etc).

2. (Optional) Enable debug for wpa_supplicant.
By default wpa_supplicant is set to MSG_INFO that doesn’t tell much.
To enable more messages:
2.1 modify common.c and set wpa_debug_level = MSG_DEBUG
2.2 modify common.h and change #define wpa_printf from if ((level) >= MSG_INFO) to if ((level) >= MSG_DEBUG)

3. Provide a proper wpa_supplicant.conf for your device
Providing a wpa_supplicant.conf it’s important because the control socket for android is specified in this file (ctrl_interface= ). This file should be copied by your AndroidBoard.mk to $(TARGET_OUT_ETC)/wifi (usually /system/etc/wifi/wpa_supplicant.conf ). This location will be used on wpa_supplicant service from init.rc.
There are two different ways in which wpa_supplicant can be configured, one is to use a “private” socket in android namespace, created by socket_local_client_connect() function in wpa_ctrl.c and another is by using a standard unix socket.

Minimum required config options in wpa_supplicant.conf :
– Android private socket

ctrl_interface=wlan0
update_config=1

– Unix standard socket

ctrl_interface=DIR=/data/system/wpa_supplicant GROUP=wifi
update_config=1

Depending on your driver you might also want to add:
ap_scan=1

If you have AP association problems with should change to ap_scan=0 to let the driver do the association instead of wpa_supplicant.
If you want to let wpa_supplicant connect to non-WPA or open wireless networks (by default it skips these kind) add:

network={
key_mgmt=NONE
}

4. Have the correct permissions and paths created from init.rc
Incorrect permisions will result in wpa_supplicant not being able to create/open the control socket and libhardware_legacy/wifi/wifi.c won’t connect.
Since Google modified wpa_supplicant to run as wifi user/group the directory structure and file ownership should belong to wifi user/group (see os_program_init() function in wpa_supplicant/os_unix.c ).

Otherwise errors like:
E/WifiHW  (  ): Unable to open connection to supplicant on “/data/system/wpa_supplicant/wlan0”: No such file or directory will appear.

Also wpa_supplicant.conf should belong to wifi user/group because wpa_supplicant will want to modify this file. If your system has /system as read-only use a location like /data/misc/wifi/wpa_supplicant.conf and modify wpa_supplicant service in init.rc with new location.
Make sure the paths are correctly created in init.rc:

mkdir /system/etc/wifi 0770 wifi wifi
chmod 0770 /system/etc/wifi
chmod 0660 /system/etc/wifi/wpa_supplicant.conf
chown wifi wifi /system/etc/wifi/wpa_supplicant.conf
#wpa_supplicant control socket for android wifi.c (android private socket)
mkdir /data/misc/wifi 0770 wifi wifi
mkdir /data/misc/wifi/sockets 0770 wifi wifi
chmod 0770 /data/misc/wifi
chmod 0660 /data/misc/wifi/wpa_supplicant.conf
chown wifi wifi /data/misc/wifi
chown wifi wifi /data/misc/wifi/wpa_supplicant.conf

If you use a Unix standard socket in wpa_supplicant.conf (see above) add:

# wpa_supplicant socket (unix socket mode)
mkdir /data/system/wpa_supplicant 0771 wifi wifi
chmod 0771 /data/system/wpa_supplicant
chown wifi wifi /data/system/wpa_supplicant

Do not add these if you use Android private socket because it will make wpa_supplicant non-functional, because hardware/libhardware_legacy/wifi/wifi.c check for existence of the /data/system/wpa_supplicant folder and will pass a wrong interface name to wpa_ctrl_open() function.

5. Make sure your wpa_supplicant and dhcpcd are starting from init.rc

For wpa_supplicant the init.rc startup like should be depending on which path you chosen:
– Android private socket:

service wpa_supplicant /system/bin/wpa_supplicant -dd -Dwext -iwlan0 -c /system/etc/wifi/wpa_supplicant.conf
socket wpa_wlan0 dgram 660 wifi wifi
group system wifi inet
disabled
oneshot

– Unix standard socket:

service wpa_supplicant /system/bin/wpa_supplicant -dd -Dwext -iwlan0 -c /system/etc/wifi/wpa_supplicant.conf
group system wifi inet
disabled
oneshot

If your wifi driver creates a wifi interface with other name than wlan0 you will have to modify the above line accordingly.
You also should have dhcpcd starting from init.rc

service dhcpcd /system/bin/dhcpcd wlan0
group system dhcp
disabled
oneshot

6. Provide your driver either as a module or built in kernel and proper kernel support for it.
First make sure that  CONFIG_PACKET and CONFIG_NET_RADIO (wireless extensions)  are enabled in your kernel. The driver can be built as module (default android way) or built in kernel (if you want to rely in kernel auto probing to support multiple driver eg. USB wifi) but will require source code modifications (see below).
– As kernel module:
Define in your BoardConfig.mk :
1. WIFI_DRIVER_MODULE_PATH := path to the module to be loaded
You need to specify module name in that path too, usually should look something like /system/lib/modules/wlan.ko
2.  WIFI_DRIVER_MODULE_NAME:= the name of the network interface that the driver creates, for example wlan0
3. WIFI_DRIVER_MODULE_ARG:= any arguments that you want to pass to the driver on insmod, for example nohwcrypt

Make sure you copy your kernel module when building android to the correct location.
– As built in kernel:
– First init.rc needs to be modified to inform hardware/libhardware_legacy/wifi/wifi.c about the name of the interface, that the driver  is already loaded and set the status of wpa_supplicant to running:

setprop wifi.interface “wlan0”
setprop wlan.driver.status “ok”

Do NOT add setprop init.svc.wpa_supplicant “running” as I previously mentioned as it will prevent wpa_supplicant from starting from init.
– Secondly hardware/libhardware_legacy/wifi/wifi.c need to be modified so the functions insmod() and rmmod() return 0 (simply add return 0; as the first line in functions since they are not needed when driver is built in kernel) and return before checking for /proc/modules in  check_driver_loaded() function.
You might encounter problems with WifiHW module not being able to connect to wpa_supplicant socket even with the correct permisions. Try to turn off / turn on Wifi from the GUI.

7. Provide a firmware if your driver needs it

If your driver needs a firmware you will have to copy this firmware file to /etc/firmware on your android build. Android doesn’t use a standard hotplug binary (although there is an implementation available on android-x86 system/code/toolbox/hotplug.c ) instead the init process takes care of firmware events and loads the firmware file from /etc/firmware (see: system/core/init/devices.c handle_firmware_event() function).
Firmware file name is defined by the driver and might also contain a folder like: RTL8192SU/rtl8192sfw.bin, entire file path should be available in /etc/firmware

8. Make your driver work with Android custom wpa_supplicant commands and SIOCSIWPRIV ioctl.

Android uses SIOCSIWPRIV ioctl to send commands to modify driver behaviour and receive information like signal strength, mac address of the AP, link speed etc. This ioctl is usually not implemented in any known wireless drivers except bcm4329 which is in google msm kernel branch .
The errors from not having this ioctl implemented will look like:
E/wpa_supplicant(  ): wpa_driver_priv_driver_cmd failed wpa_driver_priv_driver_cmd RSSI len = 4096
E/wpa_supplicant(  ): wpa_driver_priv_driver_cmd failed
D/wpa_supplicant(  ): wpa_driver_priv_driver_cmd LINKSPEED len = 4096
E/wpa_supplicant(  ): wpa_driver_priv_driver_cmd failed
I/wpa_supplicant(  ): CTRL-EVENT-DRIVER-STATE HANGED

After 4, WEXT_NUMBER_SEQUENTIAL_ERRORS errors, android will abort using the device.

To quickly test your wifi from interface you can disable error checking in external/wpa_supplicant/driver_wext.c by simply making ret = 0; in wpa_driver_priv_driver_cmd() function after the SIOCSIWPRIV ioctl call. This will make all access points in android UI appear without signal or MAC address.
To proper implement the ioctl you will need to modify your kernel driver to reply to SIOCSIWPRIV ioctl with RSSI (signal strength) and MACADDR commands being the most important.
A better way is to add a custom driver_xxx.c to google external/wpa_supplicant/ implementing wpa_driver_priv_driver_cmd() function that will take care of RSSI, MACADDR and others, through calls to SIOCGIWSTATS, SIOCGIFHWADDR ioctls, with the rest of the functions being called from driver_wext.c.
Below is a link to a patch for wpa_supplicant that I did for mini-box.com picoPC Android build. It creates a new driver awext which “emulates” android driver commands using wireless extensions ioctls.

How to use the new driver:

1. In your BoardConfig.mk define:  BOARD_WPA_SUPPLICANT_DRIVER := AWEXT
2. Change init.rc wpa_supplicant service command line by replacind -Dwext with -Dawext

AWEXT driver patch download:   android_wext_emulation_driver_awext.patch

Read original at: http://blog.linuxconsulting.ro/2010/04/porting-wifi-drivers-to-android.html

10 Comments

Android property system

Property system is an important feature on android. It runs as a service and manages system configurations and status. All these configurations and status are properties. A property is a key/value pair, both of which are of string type.

From the sense of function, it’s very similar to windows registry. Many android applications and libraries directly or indirectly relies on this feature to determine their runtime behavior. For example, adbd process queries property service to check if it’s running in emulator. Another example is the java.io.File.pathSeparator returns the value stored in property service.

How property system works

The high level architecture of property system is shown as following.
android prop sys arch
In the figure, there are three processes, a group of persistent property files and a shared memory block. The shared memory block is the container of all property records. Only the property service process can write to the shared memory block. It’ll load property records from persistent the save them in the shared memory.
The consumer process loads the shared memory in its own virtual space and access properties directly. The setter process also loads the shared memory in its virtual space, but it can’t write to the memory directly. When the setter tries to add or update a property, it sends the property to property service via unix domain socket. The property service will write the property to shared memory on behalf of the setter process, as well as to the persistent file.

Property service runs inside init process. The init process first creates a shared memory region and stores a fd to the region. Then init process maps the region into its virtual space with mmap with MAP_SHARED flag, as a result, any updates to this area can be seen by all processes. This fd and region size are saved in a environment variable named “ANDROID_PROPERTY_WORKSPACE”. Any other processes like consumer and setter will use this environment variable to get the fd and size, so that they can mmap this region into its own virtual space. The layout of the shared memory is shown below.
androi prop mem layout
After that, init process will load properties from following files:
/default.prop
/system/build.prop
/system/default.prop
/data/local.prop

The next step is start property service. In this step, a unix domain socket server is created. This socket’s pathname is “/dev/socket/property_service” which is well known to other client processes.
Finally, init process calls poll to wait for connect event on the socket.

On the consumer side, when it initializes libc(bionic/libc/bionic/libc_common.c __libc_init_common function). It will retrieve the fd and size from environment variable, and map the shared memory into its own space(bionic/libc/bionic/system_properties.c __system_properties_init function). After that, libcutils can read property just as normal memory for the consumer.

Currently, properties can’t be removed. That’s to say, once a property has been added, it can’t be removed, neither can its key be changed.

How to get/set properties

There are three main means to get/set properies on android.

1. native code
When writing native applications, property_get and property_set APIs can be used to get/set properties. To use them, we need to includecutils/properties.h and link against libcutils.

2. java code
Android also provides System.getProperty and System.setProperty functions in java library, our java application can use them to get/set properties.

But it’s important to note that although these java APIs are semantically equal to native version, java version store data in a totally different place. Actually, a hashtable is employed by dalvik VM to store properties. So, java properties are separated, it can’t get or set native properties, and neither vice versa.

Update: Andrew mentioned that android.os.SystemProperties class can manipulate native properties, though it’s intended for internal usage only. It calls through jni into native property library to get/set properties.

3. shell script
Android provides getprop and setprop command line tool to retrieve and update properties. They can be used in shell script. They are implemented on top of libcutils.

Another good tip is to check ./system/core/init/property_service.c , there you can figure out how permissions work.

Leave a comment

Compiling Busybox to play around with Android & ARM

Download source code from git:

$ git clone git://busybox.net/busybox.git
$ cd busybox/

Export ARCH and CROSS_COMPILE

$ export ARCH=arm
$ export CROSS_COMPILE=/opt/gcc-4.1.2-glibc-2.5-nptl-3/arm-none-linux-gnueabi/bin/arm-none-linux-gnueabi-
$ make menuconfig

In menuconfig set the following options

$ Busybox Settings --> Build Options --> Build Busybox as a static binary (no shared libs)  -  Enable this option by pressing "Y"
$ Busybox Settings --> Build Options --> Cross compiler prefix  -  Set this option equal to "arm-none-linux-gnueabi-"
$ Busybox Settings --> Installation Options --> Don't use /usr  -  Enable this option by pressing "Y"
$ Linux Module Utilities --> () Default directory containing modules - Set this option to nothing
$ Linux Module Utilities --> () Default name of modules.dep - Set this option to nothing
Compile it using make
$ make
$ file busybox
busybox: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, for GNU/Linux 2.6.14, stripped

Upload the file busybox to your device and instal it from the device console:

$./busybox --install -s

More info available at:
http://omapzoom.org/wiki/Android_Installing_Busybox_Command_Line_Tools

2 Comments

Android on iMx51EVK with 3G modem

You can find the original article here http://sites.google.com/site/fslnovi/imx-demos/imx51-babbage-demos/android-on-bbg25

Android Installation  

1. Install JDK

Install JDK 5 from here :
http://java.sun.com/javase/downloads/index_jdk5.jsp

NOTE : JDK 6 is not compatible. JDK 5 is essential

Installation notes for JDK 5 are here:
http://java.sun.com/j2se/1.5.0/install-linux.html
Download the .bin file into /usr/java and install

2. Setup other packages for Android based on instructions here :
http://source.android.com/source/download.html

3. Edit ~/.profile and add the following commands :

export ARCH=arm
export CROSS_COMPILE=/opt/gcc-4.1.2-glibc-2.5-nptl-3/arm-none-linux-gnueabi/bin/arm-none-linux-gnueabi-
export JAVA_HOME=/usr/java/jdk1.5.0_22
export ANDROID_JAVA_HOME=$JAVA_HOME
export PATH=$JAVA_HOME/bin:$PATH

4. gcc-4.3 and g++4.3 must be installed to compile the SDK.

However, gcc and g++ installed using sudo apt-get install will pull in gcc4.4 and g++4.4
This will not lead to issues in compilation.

Follow all the steps in User guide.

Errors during build : https://sites.google.com/site/fslnovi/imx-demos/imx51-babbage-demos/android-on-bbg25/android-error

Hardware for USB Modem

Huawei E180
Bought from : http://cgi.ebay.com.au/ws/eBayISAPI.dll?ViewItem&item=220459919467
Reference manual : http://www.meteor.ie/rubylith/files/mbb/Meteor%20Mobile%20Broadband%20Trial%20Quick%20start%20guide.pdf

SIM Card
Tmobile 3G with voice and data plan

How to get Log messages ?

Connect 3G module with SIM inserted and then bootup to Android shell:
$ dmesg
$ ls /dev/ttyUSB*
$ logcat -b radio &
$ logcat pppd:* *:S &

* E180 is identified by kernel as two USB serial ports:
# ls /dev/ttyUSB*
/dev/ttyUSB0
/dev/ttyUSB1

But our default configuration for RIL daemon is to listen on ttyUSB3. So change /init.rc as below:
service ril-daemon .... -d /dev/ttyUSB3 -u /dev/ttyUSB0
->
service ril-daemon --- -d /dev/ttyUSB1 -u /dev/ttyUSB0

init.rc is in the root partition of Android root filesystem. After you build Android, it's under ~/myAndroid/out/target/product/imx51_BBG/

How to change init.rc and integrate into rootfs ?
On host machine
$ cd ~/myAndroid
$ rm out/target/imx51_BBG/ramdisk.img
$ CHANGE out/target/imx51_BBG/root/init.rc per your needs
$ make
ramdisk.img will be re-generated
or if you don't want to make whole Android, you can:
$
out/host/linux-x86/bin/mkbootfs out/target/product/imx51_BBG/root | out/host/linux-x86/bin/minigzip > out/target/product/imx51_BBG/ramdisk.img

If you only have ramdisk.img but don't have corresponding "root/" directory, you can get it by:
$ gunzip ramdisk.img
$ mkdir root
$ cd root
$ sudo cpio -i --make-directories < ../ramdisk.img
$ ls
Now you have your "root/". You can change anything (e.g. init.rc) and the re-create the ramdisk.img with method above.

How to detect that you are connected to the network ?

The entire log is attached. But the following sections indicate connection was successful. 

D/GSM     ( 2057): [GsmDataConnectionTracker] setState: INITING
D/AT      ( 1955): AT< OK
D/AT      ( 1955): AT> AT+CGQREQ=1
D/AT      ( 1955): AT< OK
D/AT      ( 1955): AT> AT+CGQMIN=1
D/AT      ( 1955): AT< OK
D/AT      ( 1955): AT> AT+CGEREP=1,0
D/AT      ( 1955): AT< OK
D/AT      ( 1955): AT> AT+CGACT=0,1
D/AT      ( 1955): AT< OK
D/AT      ( 1955): AT> ATD*99***1#
D/AT      ( 1955): AT< CONNECT 236800
D/RIL     ( 1955): PPPd started

The other obvious check would be to check if we get an IP address. 

Sometimes, if you are booting from SD, the excetution mode of "/etc/init.gprs-pppd" is not set which will cause it to fail while bringing up PPP.
To fix this, you need to change the mode in system partition on the SD card after connecting it to the linux host. 

$ chmod 777 /etc/init.gprs-pppd

Radio Interface Layer Sites
----------------------------
a. http://www.netmite.com/android/mydroid/development/pdk/docs/telephony.html
b. http://i-miss-erin.blogspot.com/2009/11/radio-layer-interface-in-android.html 

Android Developers Site
-----------------------
a. http://developer.android.com/guide/index.html

1 Comment

ADB over TCP

To make ADB work in iMX51 using TCP:

*In your host machine:

– Install android SDK
– export ADBHOST=BOARD_IP (setenv ADBHOST=xxx.xxx.xxx.xxx)
– adb kill-server

*In your board:

– make sure that  ro.secure property is *not* set when the adbd daemon is launched, so edit the file default.prop
– make sure that /dev/android_adb or /dev/android do *not* exist
– stop adbd
– start adbd

Now you will be able to list the device:

hamilton@saygon:/opt/work/androidsdk/android-sdk-linux_86/tools$ ./adb kill-server
hamilton@saygon:/opt/work/androidsdk/android-sdk-linux_86/tools$ ./adb devices
* daemon not running. starting it now *
* daemon started successfully *
List of devices attached
emulator-5554   device

Leave a comment

Android DNS configuration

# DNS

setprop net.dns1 server_ip

setprop net.dns2 server_ip

Leave a comment