Category Archives: Android

Android Low-Level System Architecture


Porting Android to Devices

Android provides you with the freedom to implement your own device specifications and the drivers to support them. The hardware abstraction layer (HAL) gives you a standard way to create software hooks in between the Android platform stack and your hardware. In addition, the Android operating system is open-sourced to help you through your device’s bringup.

To ensure that your devices maintain a high level of quality and offers a consistent experience for your users, they must must also pass the tests in the compatibility test suite (CTS). CTS ensures that anyone building a device meets a quality standard that ensures apps run reliabaly well and gives users a good experience. For more information, see the Compatibility section.

Android Low-Level System Architecture

Before you begin porting Android to your hardware, it is important to have an understanding of how Android works at a high level. Because your drivers and HAL code interact with many layers of Android code, this understanding can help you find your way through the many layers of code that are available to you through the AOSP (Android Open Source Project) source tree. The following diagram shows a system level view of how Android works:

Figure 1. Android System Architecture

Application framework

This is the level that most application developers concern themselves with. You should be aware of the APIs available to developers as many of them map 1:1 to the underlying HAL interfaces and can provide information as to how to implement your driver.

Binder IPC

The Binder Inter-Process Communication mechanism allows the application framework to cross process boundaries and call into the Android system services code. This basically allows high level framework APIs to interact with Android’s system services. At the application framework level, all of this communication is hidden from the developer and things appear to “just work.”

System services

Most of the functionality exposed through the application framework APIs must communicate with some sort of system service to access the underlying hardware. Services are divided into modular components with focused functionality such as the Window Manager, Search Service, or Notification Manager. System services are grouped into two buckets: system and media. The system services include things such as the Window or Notification Manager. The media services include all the services involved in playing and recording media.

Hardware abstraction layer (HAL)

The HAL serves as a standard interface that allows the Android system to call into the device driver layer while being agnostic about the lower-level implementations of your drivers and hardware. You must implement the corresponding HAL (and driver) for the particular piece of hardware that your product provides. Android does not mandate a standard interaction between your HAL implementation and your device drivers, so you have free reign to do what is best for your situation. However, you must abide by the contract defined in each hardware-specific HAL interface for the Android system to be able to correctly interact with your hardware. HAL implementations are typically built into shared library modules (.so files).

Linux Kernel

For the most part, developing your device drivers is the same as developing a typical Linux device driver. Android uses a specialized version of the Linux kernel with a few special additions such as wakelocks, a memory management system that is more agressive in preserving memory, the Binder IPC driver, and other features that are important for a mobile embedded platform like Android. These additions have less to do with driver development than with the system’s functionality. You can use any version of the kernel that you want as long as it supports the required features, such as the binder driver. However, we recommend using the latest version of the Android kernel. For the latest Android kernel, see Building Kernels.


downgrade nexus s from 4.1.x to 2.3.6

after upgrading nexus s to 4.1.2, it’s not straight forward to downgrade to 2.3.6. A error occurs when fastboot -w update


fastbooot flash recovery recovery-clockwork- (which is downloaded from the Internet)

boot to bootloader, enter recovery mode, install rom (zip file in sdcard) from zip, which is downloaded from the Internet.

I’m not sure the rom is official rom as later there comes errors, A flashable rom is a zip file with boot.img, bootloader.img, radio.img and system folder, recovery folder and META-INF folder.

After that, the older version android is installed.

But when the system starts, there comes a lot of package crash errors and I’m not able to enter the system.

Then I flash the older version factory img with regular steps. It succeeds.


Ps: nexus S adb driver need to be downloaded from Samsung,

Flashing Android IMG

Recently, I made some changes to android webkit and compile android source. Then I need to flash my android Nexus S with the fresh built img.

(fastboot is a command/executable like adb)

0. unlock bootloader

note: in order for fastboot and adb commands to find devices, the right usb driver needed to be installed through Window device manager. In device manager, right click on devices (with a ‘?’ on it if driver is not installed), update driver from local file system (sdk–extras–google–driver). Sometimes, if “adb devices” cannot find devices, just try another usb port of your computer.

$ fastboot oem unlock

  1. Reboot bootloader

    $ fastboot reboot-bootloader

  2. flash android image

$ fastboot -w update

  • note that there’re several img files in the zip file, userdata.img, system.img, boot.img, recovery.img, we can just make the compress the img files into a zip file.
  • before compiling android source for specific device, we need to get the proprietary binaries and extract them under root directory of android source. (

But after flash the self-made android image, I find that the Google apps do not exit in this build, like Google Play. I can’t even log my Google account on for this device. So What I need to do is to install the so-called Google_apps from a zip package (downloaded from I put the zip file on sdcard, reboot to fastboot mode, enter recover mode (I downloaded the latest TWRP custom recovery image from, update/install from sdcard using the zip file. Then I reboot, the google play app and other Google apps exist in the system now.

But i find that i can’t log onto my google account for google play store. So i have to install apps (for experiment of my research) through “adb install xxx.apk” command. Here’s the batch file for windows (apks and adb.exe are in the same directory):

for /r . %%g in (*.apk) do 
@echo %%g
adb install %%g

several ago, i wrote one for Ubuntu:

for f in $FILES
echo “Processing $f file…”
adb install $f
echo “finished instaling $f file…”
# take action on each file. $f store current file name
# cat $f

Decompile apks (batch)

use command apktool to decompile a bunch of apks on windows: (apktool d xxx.apk)

for /r . %%g in (*.apk) do apktool d %%g 

use dex2jar to decompile a bunch of apks on windows: (d2j-dex2jar.bat xxx.apk)

for /r . %%g in (*.apk) do ..\d2j-dex2jar.bat %%g




Debugging Webkit/Android native code


Debugging with GDB

In this document


Configure debug build (from Xinshu Dong)
This is to build WebKit in debug mode. Under the Android source directory, run ‘cp
build/’. Open to edit, and append the following

The current version of has a gdbclient command that handles much of the setup. For example, to attach the already-running globaltime application, execute the following, making sure that: 1) you do this from the same window used to build the software on the device you are debugging and 2) verify that the symbols in the object files in the build tree match up with what is installed on the device or emulator.

gdbclient app_process :5039 globaltime


Short Instructions

Android runs gdbserver on the device and an ARM aware gdb, named arm-eabi-gdb, on the desktop machine.

  1. First you need to run gdbserver on the device:
    	gdbserver :5039 /system/bin/executable

    The :5039 tells gdbserver to listen on port 5039 on the localhost, which adb bridges from the host to the device. executable represents the command to debug, a common one being runtime -s which starts the entire system all running in a single process.

  2. Launch gdb on the desktop. This can be done easily with the following command in the shell from which you built:
    gdbclient executable

At this point gdb will connect with your device and you should be able to enter c to have the device start executing inside of the desktop gdb session.

Detailed Instructions

If the short instructions don’t work, these detailed instructions should:

  1. On the device, launch a new command:
    gdbserver :5039 /system/bin/executable

    or attach to an existing process:

    gdbserver :5039 --attach pid
  2. On your workstation, forward port 5039 to the device with adb:
    adb forward tcp:5039 tcp:5039
  3. Start a special version of gdb that lives in the “prebuilt” area of the source tree:
    prebuilt/Linux/toolchain-eabi-4.2.1/bin/arm-eabi-gdb (for Linux)
    prebuilt/darwin-x86/toolchain-eabi-4.2.1/bin/arm-eabi-gdb (for Darwin)
  4. If you can’t find either special version of gdb, run find prebuilt -name arm-eabi-gdb in your source tree to find and run the latest version:
    prebuilt/Linux/toolchain-eabi-4.2.1/bin/arm-eabi-gdb  out/target/product/product-name/symbols/system/bin/executable

    Where product-name is the name of the device product that you’re building (for example, sooner), and executable is the program to debug (usually app_process for an application).

    Make sure to use the copy of the executable in the symbols directory, not the primary android directory, because the one in the primary directory has been stripped of its debugging information.

  5. In gdb, Tell gdb where to find the shared libraries that will get loaded:
    set solib-absolute-prefix /absolute-source-path/out/target/product/product-name/symbols
    set solib-search-path /absolute-source-path/out/target/product/product-name/symbols/system/lib

    absolute-source-path is the path to your source tree; for example, /work/device or /Users/hoser/android/device.
    product-name is the same as above; for example, sooner.

    Make sure you specify the correct directories—gdb may not tell you if you make a mistake.

  6. Connect to the device by issuing the gdb command:
    target remote :5039

    The :5039 tells gdb to connect to the localhost port 5039, which is bridged to the device by adb.

    You may need to inspire gdb to load some symbols by typing:


You should be connected and able to debug as you normally would. You can ignore the error about not finding the location for the thread creation breakpoint. It will be found when the linker loads libc into your process before hitting main(). Also note that the gdb remote protocol doesn’t have a way for the device to tell the host about newly created threads so you will not always see notifications about newly created threads. Info about other threads will be queried from the device when a breakpoint is hit or you ask for it by running info thread.

Just-In-Time Debug Feature

If you see the red LED flashing it means a process is in that new state (crashed and waiting for GDB connection). If this happens to the system process, most likely your device will be frozen at this point. Do not press the home key. Bring the device to someone who can debug native crashes and ask for advice. If you’re in the field and just want your device to continue as it would have without this feature (like cylonning), press home (a tombstone will be recorded as usual). To enable a process to be debugged this way, you need to set a property:

adb shell setprop debug.db.uid 10000

and all processes with a uid <= 10000 will be trapped in this manner. When one of them crashes, the tombstone is processed as usual, an explicit message is printed into the log, and the red LED starts flashing waiting for the Home key to be depressed (in which case it continues execution as usual).

I/DEBUG   (   27): ********************************************************
I/DEBUG   (   27): * process 82 crashed. debuggerd waiting for gdbserver
I/DEBUG   (   27): *
I/DEBUG   (   27): *     adb shell gdbserver :port --attach 82 &
I/DEBUG   (   27): *
I/DEBUG   (   27): * and press the HOME key.
I/DEBUG   (   27): ********************************************************

When you see the entry above, make sure adb is forwarding port 5039 (you only need to do this once, unless the ADB server dies) and execute:

% adb forward tcp:5039 tcp:5039

Execute the line shown in the debug output, substituting 5039 for the proper port:

% adb shell gdbserver :5039 --attach 82 &

If the crashing process is based off zygote (that is, system_server and all applications), the default values for the gdbclient command, app_process binary and port 5039, are correct, so you can execute:

% cd <top of device source tree>
% gdbclient

Otherwise you need to determine the path of the crashing binary and follow the steps as mentioned above (for example, gdbclient hoser :5039 if the hoser command has failed).