http://armadeus.org/wiki/api.php?action=feedcontributions&feedformat=atom&user=BenjaminC
ArmadeusWiki - User contributions [en]
2026-06-30T13:15:44Z
User contributions
MediaWiki 1.26.3
http://armadeus.org/wiki/index.php?title=Android&diff=7622
Android
2009-11-16T19:38:37Z
<p>BenjaminC: small typo</p>
<hr />
<div>[[Image:Android-logo.png]]<br />
<br />
This page will sumarize the efforts made to have Android running on the APF boards.<br />
<br />
{{Note| Due to Android requirements (at least an ARM926 core), it is impossible to have it running on the APF9328}}<br />
<br />
==Some readings before starting==<br />
* http://developer.android.com/guide/basics/what-is-android.html<br />
<br />
==Prerequisites for Android installation==<br />
===Install needed software packages===<br />
* Install these package for build the kernel image and for format the mmc/µSD card<br />
<pre class="host"><br />
sudo apt-get install uboot-mkimage mtd-utils<br />
</pre><br />
* The Armadeus [[Toolchain]], only for Armadeus patches<br />
<br />
===Update the environment variables===<br />
Theses environment variables install the Android and Armadeus folder in our home directory, but of course, it can be placed anywhere!<br />
<pre class="config"><br />
export ANDROID_SOURCE=~/android-eclair<br />
export ANDROID_KERNEL=~/android-kernel<br />
export ANDROID_SDK=~/android-sdk-linux<br />
export ARMADEUS=~/armadeus-3.1<br />
export PATH=${PATH}:${ANDROID_SDK}/tools:${ANDROID_SOURCE}/bin<br />
</pre><br />
<br />
===Download Android source===<br />
List of different Android branch: [http://android.git.kernel.org/?p=platform/manifest.git;a=heads heads]<br />
The [http://source.android.com/download getting Android source] document describes how to set up our local work environment. <br />
Follow theses instructions until ''Installing Repo'' chapter.<br />
<pre class="host"><br />
mkdir $ANDROID_SOURCE<br />
cd $ANDROID_SOURCE<br />
mkdir bin<br />
curl http://android.git.kernel.org/repo >$ANDROID_SOURCE/bin/repo<br />
chmod a+x $ANDROID_SOURCE/bin/repo<br />
repo init -u git://android.git.kernel.org/platform/manifest.git -b eclair<br />
repo sync<br />
</pre><br />
<br />
Since android-sdk-1.5_r3 branch, the Linux kernel isn't with the Android source, <br />
We can download it in a compress archive (tar.gz) file with this [http://android.git.kernel.org/?p=kernel/common.git;a=snapshot;h=refs/heads/android-2.6.29;sf=tgz android-kernel-2.6.29] (about (70Mib) or with git repository (more 300Mib)<br />
<pre class="host"><br />
mkdir $ANDROID_KERNEL<br />
cd $ANDROID_KERNEL<br />
git clone git://android.git.kernel.org/kernel/common.git android-2.6.29<br />
</pre><br />
<br />
==Linux Kernel 2.6.29==<br />
===Apply the Armadeus patchset===<br />
Before compiling the kernel, we patch the source with the Armadeus patches. In second time, I will give the URL to retrieve Linux 2.6.29.4 patch.<br />
{{Warning| Never export ARCH and CROSS_COMPILE environment variables because Android make use them too}}<br />
<pre class="host"><br />
$ARMADEUS/buildroot/toolchain/patch-kernel.sh $ANDROID_KERNEL $ARMADEUS/downloads patch-2.6.29.4.bz2<br />
$ARMADEUS/buildroot/toolchain/patch-kernel.sh $ANDROID_KERNEL $ARMADEUS/buildroot/target/device/armadeus/linux/kernel-patches/2.6.29.4 \*.patch{,.gz,.bz2}<br />
mkdir $ANDROID_KERNEL/drivers/armadeus<br />
cp -r $ARMADEUS/target/linux/modules/* $ANDROID_KERNEL/drivers/armadeus<br />
</pre><br />
<br />
For generate the Linux kernel, we retrieve the default apf27 Linux configuration and modify it for start Android.<br />
<pre class="host"><br />
cp $ARMADEUS/buildroot/target/device/armadeus/apf27/apf27-linux-2.6.29.config $ANDROID_KERNEL/arch/arm/configs/apf27_android_defconfig<br />
cd $ANDROID_KERNEL<br />
make ARCH=arm mrproper<br />
make ARCH=arm apf27_android_defconfig<br />
make ARCH=arm menuconfig<br />
</pre><br />
===Android kernel configuration===<br />
Make sure your kernel boots normally on your board. Then enable some Android specific configuration and make sure that your kernel still boots (with your standard file system).<br />
* Activate the Android pmem allocator<br />
<pre class="config"><br />
Device Drivers ---><br />
[*] Misc devices ---><br />
[*] Android pmem allocator<br />
</pre><br />
* Activate the Android drivers<br />
<pre class="config"><br />
Device Drivers ---><br />
[*] Staging drivers ---> <br />
[ ] Exclude Staging drivers from being built (NEW)<br />
...<br />
Android ---><br />
[*] Android Drivers<br />
[*] Android Binder IPC Driver<br />
<*> Android log driver <br />
[ ] Android RAM buffer console<br />
[*] Timed output class driver (NEW)<br />
< > Android timed gpio driver (NEW)<br />
[*] Android Low Memory Killer <br />
</pre><br />
* Activate the Anonymous Shared Memory Subsystem<br />
<pre class="config"><br />
General setup ---><br />
[*] Enable the Anonymous Shared Memory Subsystem<br />
</pre><br />
<br />
===Touchscreen kernel configuration===<br />
* Activate the wake lock for spi event reach to Android and include in the compiled kernel the touchscreen driver<br />
<pre class="config"><br />
Power management options ---><br />
[*] Wake lock<br />
[*] Wake lock stats (NEW)<br />
[*] Userspace wake locks (NEW)<br />
[*] Early suspend (NEW) <br />
User-space screen access (Console switch on early-suspend) ---><br />
(X) Sysfs interface <br />
...<br />
Device Drivers ---><br />
Input device support ---><br />
[*] Touchscreens ---><br />
<*> TSC 2102 based touchscreens<br />
...<br />
<*> Hardware Monitoring support ---><br />
</pre><br />
===Audio kernel configuration===<br />
* Include in the compiled kernel the audio driver<br />
<pre class="config"><br />
Device Drivers ---><br />
<*> Sound card support ---><br />
--- Sound card support<br />
<*> Advanced Linux Sound Architecture ---><br />
[*] ARM sound devices ---><br />
--- ARM sound <br />
<*> i.MX27 SSI driver<br />
<*> TSC210x alsa driver<br />
</pre><br />
===Modify touchscreen driver===<br />
Android don't use tslib library so we should add the calibration directly in ts drivers<br><br />
edit ''$ANDROID_KERNEL/drivers/input/touchscreen/tsc2102_ts.c''<br><br />
Add new definitions for X and Y ranges<br />
<source lang="c"><br />
#define DRIVER_NAME "TSC210x Touchscreen"<br />
#define X_AXIS_MAX 4000<br />
#define X_AXIS_MIN 0<br />
#define Y_AXIS_MAX 4200<br />
#define Y_AXIS_MIN 100<br />
#define PRESSURE_MIN 20<br />
#define PRESSURE_MAX 40000<br />
#define FACTOR 5000<br />
</source><br />
Send touch event to Android when the user release the touchscreen<br />
<source lang="c"><br />
static void tsc210x_touch(int touching)<br />
{<br />
if (!touching) {<br />
//input_report_abs(dev, ABS_X, 0);<br />
//input_report_abs(dev, ABS_Y, 0);<br />
input_report_key(dev, BTN_TOUCH, 0);<br />
input_report_abs(dev, ABS_PRESSURE, 0);<br />
input_sync(dev);<br />
}<br />
<br />
//input_report_key(dev, BTN_TOUCH, touching);<br />
//do_poke_blanked_console = 1;<br />
}<br />
</source><br />
<source lang="c"><br />
static void tsc210x_coords(int x, int y, int z1, int z2)<br />
{<br />
int p;<br />
<br />
/* Calculate the touch resistance a la equation #1 */<br />
if (z1 != 0)<br />
p = x * (z2 - z1) / (z1 << 4) * FACTOR;<br />
else<br />
p = 1;<br />
<br />
y = Y_AXIS_MAX - y;<br />
input_report_key(dev, BTN_TOUCH, 1);<br />
input_report_abs(dev, ABS_X, x);<br />
input_report_abs(dev, ABS_Y, y);<br />
input_report_abs(dev, ABS_PRESSURE, p);<br />
input_sync(dev);<br />
}<br />
</source><br />
Calibrate the touchscreen with X and Y ranges<br />
<source lang="c"><br />
static int tsc210x_ts_probe(struct platform_device *pdev)<br />
{<br />
int status;<br />
<br />
dev = input_allocate_device();<br />
if (!dev)<br />
return -ENOMEM;<br />
<br />
status = tsc210x_touch_cb(tsc210x_touch);<br />
if (status)<br />
{<br />
goto error;<br />
}<br />
<br />
status = tsc210x_coords_cb(tsc210x_coords);<br />
if (status)<br />
{<br />
goto error;<br />
}<br />
<br />
dev->name = DRIVER_NAME;<br />
dev->dev.parent = &pdev->dev;<br />
dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);<br />
dev->keybit[BIT_WORD(BTN_TOUCH)] |= BIT_MASK(BTN_TOUCH);<br />
dev->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | BIT_MASK(ABS_PRESSURE);<br />
input_set_abs_params(dev, ABS_X, X_AXIS_MIN, X_AXIS_MAX, 0, 0);<br />
input_set_abs_params(dev, ABS_Y, Y_AXIS_MIN, Y_AXIS_MAX, 0, 0);<br />
input_set_abs_params(dev, ABS_PRESSURE, PRESSURE_MIN, PRESSURE_MAX, 0, 0);<br />
status = input_register_device(dev);<br />
if (status)<br />
{<br />
printk(KERN_INFO "Unable to register TSC210x as input device !\n");<br />
goto error;<br />
}<br />
<br />
printk(DRIVER_NAME " driver initialized\n");<br />
return 0;<br />
<br />
error:<br />
input_free_device(dev);<br />
return status;<br />
}<br />
</source><br />
===Build Android kernel===<br />
Compile the kernel and generate image kernel for U-Boot Loader<br />
<pre class="host"><br />
cd $ANDROID_KERNEL<br />
make ARCH=arm CROSS_COMPILE=$ANDROID_SOURCE/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi- uImage<br />
cp $ANDROID_KERNEL/arch/arm/boot/uImage $TFTPBOOT/apf27-linux.bin<br />
</pre><br />
<br />
==Android==<br />
===Battery patch===<br />
At the beginning, reboot happened over again even though Android logo appeared on board.<br />
Result of investigation, we found that battery power was returned with 0 when boot.. Then, we changed to notify full battery to Android by ignoring the information under ''/sys/class/power_supply'' so that to prevent the power down by low battery ''$ANDROID_SOURCE/frameworks/base/services/jni/com_android_server_BatteryService.cpp''<br />
*Change the battery service status as TRUE<br />
<source lang="c"><br />
static void setBooleanField(JNIEnv* env, jobject obj, const char* path, jfieldID fieldID)<br />
{<br />
const int SIZE = 16;<br />
char buf[SIZE];<br />
<br />
jboolean value = true; /* change false -> true */<br />
/*!!!comment out!!!<br />
if (readFromFile(path, buf, SIZE) > 0) {<br />
if (buf[0] == '1') {<br />
value = true;<br />
}<br />
}<br />
*/<br />
env->SetBooleanField(obj, fieldID, value);<br />
}<br />
</source><br />
*Change the volume, voltage and temperature of battery. Return 100%.<br />
<source lang="c"><br />
static void setIntField(JNIEnv* env, jobject obj, const char* path, jfieldID fieldID)<br />
{<br />
const int SIZE = 128;<br />
char buf[SIZE];<br />
<br />
jint value = 100; /* change 0 -> 100 */<br />
/*!!!comment out!!!<br />
if (readFromFile(path, buf, SIZE) > 0) {<br />
value = atoi(buf);<br />
}<br />
*/<br />
env->SetIntField(obj, fieldID, value);<br />
}<br />
</source><br />
* Change the battery charged status as full and deterioration status as fair.<br />
<source lang="c"><br />
static void android_server_BatteryService_update(JNIEnv* env, jobject obj)<br />
{<br />
setBooleanField(env, obj, AC_ONLINE_PATH, gFieldIds.mAcOnline);<br />
setBooleanField(env, obj, USB_ONLINE_PATH, gFieldIds.mUsbOnline);<br />
setBooleanField(env, obj, BATTERY_PRESENT_PATH, gFieldIds.mBatteryPresent);<br />
<br />
setIntField(env, obj, BATTERY_CAPACITY_PATH, gFieldIds.mBatteryLevel);<br />
setIntField(env, obj, BATTERY_VOLTAGE_PATH, gFieldIds.mBatteryVoltage);<br />
setIntField(env, obj, BATTERY_TEMPERATURE_PATH, gFieldIds.mBatteryTemperature);<br />
<br />
/* Change */<br />
env->SetIntField(obj, gFieldIds.mBatteryStatus, gConstants.statusFull);<br />
env->SetIntField(obj, gFieldIds.mBatteryHealth, gConstants.healthGood);<br />
env->SetObjectField(obj, gFieldIds.mBatteryTechnology, env->NewStringUTF("1"));<br />
<br />
/*!!!comment out!!!<br />
const int SIZE = 128;<br />
char buf[SIZE];<br />
<br />
if (readFromFile(BATTERY_STATUS_PATH, buf, SIZE) > 0)<br />
env->SetIntField(obj, gFieldIds.mBatteryStatus, getBatteryStatus(buf));<br />
<br />
if (readFromFile(BATTERY_HEALTH_PATH, buf, SIZE) > 0)<br />
env->SetIntField(obj, gFieldIds.mBatteryHealth, getBatteryHealth(buf));<br />
<br />
if (readFromFile(BATTERY_TECHNOLOGY_PATH, buf, SIZE) > 0)<br />
env->SetObjectField(obj, gFieldIds.mBatteryTechnology, env->NewStringUTF(buf));<br />
*/<br />
}<br />
</source><br />
<br />
===Audio===<br />
For activate the audio, we should retrieve Alsa android module whose not directly add in the source<br />
<pre class="host"><br />
cd $ANDROID_SOURCE/external<br />
git clone git://android.git.kernel.org/platform/external/alsa-lib.git<br />
git clone git://android.git.kernel.org/platform/external/alsa-utils.git<br />
cd $ANDROID_SOURCE/hardware <br />
git clone git://android.git.kernel.org/platform/hardware/alsa_sound.git<br />
</pre><br />
<br />
edit ''$ANDROID_SOURCE/build/target/board/generic/BoardConfig.mk'' and modify the audio divers used by Android<br />
<pre class="config"> <br />
# HAVE_HTC_AUDIO_DRIVER := true<br />
# BOARD_USES_GENERIC_AUDIO := true<br />
BOARD_USES_ALSA_AUDIO := true<br />
BUILD_WITH_ALSA_UTILS := true<br />
</pre><br />
<br />
edit ''$ANDROID_SOURCE/hardware/alsa_sound/AudioHardwareALSA.cpp'' and change bufferSize to 8192 in twice StreamDefaults structures <br><br />
edit ''$ANDROID_SOURCE/system/core/init/devices.c'' and add audio device in Linux devices<br />
<source lang="c"><br />
static struct perms_ devperms[] = {<br />
{ "/dev/null", 0666, AID_ROOT, AID_ROOT, 0 },<br />
...<br />
{ "/dev/qmi1", 0640, AID_RADIO, AID_RADIO, 0 },<br />
{ "/dev/qmi2", 0640, AID_RADIO, AID_RADIO, 0 },<br />
// Add this line<br />
{ "/dev/snd/", 0664, AID_SYSTEM, AID_AUDIO, 1 },<br />
{ NULL, 0, 0, 0, 0 },<br />
};<br />
</source><br />
<br />
<source lang="c"><br />
static void handle_device_event(struct uevent *uevent)<br />
{<br />
char devpath[96];<br />
char *base, *name;<br />
int block;<br />
...<br />
} else if(!strncmp(uevent->subsystem, "mtd", 3)) {<br />
base = "/dev/mtd/";<br />
mkdir(base, 0755);<br />
// add this conditionnal block<br />
} else if(!strncmp(uevent->subsystem, "sound", 5)) {<br />
base = "/dev/snd/";<br />
mkdir(base, 0755);<br />
} else if(!strncmp(uevent->subsystem, "misc", 4) &&<br />
!strncmp(name, "log_", 4)) {<br />
base = "/dev/log/";<br />
mkdir(base, 0755);<br />
name += 4;<br />
} else<br />
base = "/dev/";<br />
}<br />
</source><br />
Add audio files in Android files system<br />
<pre class="host"><br />
mkdir $ANDROID_SOURCE/system/core/rootdir/media <br />
mkdir $ANDROID_SOURCE/system/core/rootdir/media/audio <br />
mkdir $ANDROID_SOURCE/system/core/rootdir/media/audio/ui<br />
mkdir $ANDROID_SOURCE/system/core/rootdir/media/audio/alarms <br />
mkdir $ANDROID_SOURCE/system/core/rootdir/media/audio/notifications <br />
mkdir $ANDROID_SOURCE/system/core/rootdir/media/audio/ringtones <br />
cp $ANDROID_SOURCE/frameworks/base/data/sounds/effects/* $ANDROID_SOURCE/system/core/rootdir/media/audio/ui/ <br />
cp $ANDROID_SOURCE/frameworks/base/data/sounds/Alarm_* $ANDROID_SOURCE/system/core/rootdir/media/audio/alarms/<br />
cp $ANDROID_SOURCE/frameworks/base/data/sounds/notifications/* $ANDROID_SOURCE/system/core/rootdir/media/audio/notifications/<br />
cp $ANDROID_SOURCE/frameworks/base/data/sounds/Ring_* $ANDROID_SOURCE/system/core/rootdir/media/audio/ringtones/<br />
</pre><br />
<br />
===Android start up===<br />
Edit ''$ANDROID_SOURCE/system/core/rootdir/init.rc'', comment the '''mount roofs''' in read only mode and '''mount yaffs2''' lines like this:<br />
<pre class="config"><br />
# setup the global environment<br />
export PATH /sbin:/system/sbin:/system/bin:/system/xbin<br />
export LD_LIBRARY_PATH /system/lib<br />
export ANDROID_BOOTLOGO 1<br />
export ANDROID_ROOT /system<br />
export ANDROID_ASSETS /system/app<br />
export ANDROID_DATA /data<br />
export EXTERNAL_STORAGE /sdcard<br />
export BOOTCLASSPATH /system/framework/core.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar<br />
<br />
mount rootfs rootfs / rw remount<br />
<br />
# Backward compatibility<br />
symlink /system/etc /etc<br />
<br />
# create mountpoints and mount tmpfs on sqlite_stmt_journals<br />
mkdir /sdcard 0000 system system<br />
mkdir /system<br />
mkdir /data 0771 system system<br />
mkdir /cache 0770 system cache<br />
mkdir /sqlite_stmt_journals 01777 root root<br />
mount tmpfs tmpfs /sqlite_stmt_journals size=4m<br />
<br />
mount rootfs rootfs / ro remount<br />
<br />
write /proc/sys/kernel/panic_on_oops 1<br />
write /proc/sys/kernel/hung_task_timeout_secs 0<br />
write /proc/cpu/alignment 4<br />
write /proc/sys/kernel/sched_latency_ns 10000000<br />
write /proc/sys/kernel/sched_wakeup_granularity_ns 2000000<br />
<br />
# mount mtd partitions<br />
# Mount the SD Card partition<br />
setprop EXTERNAL_STORAGE_STATE mounted<br />
mount vfat /dev/block/mmcblk0p1 /sdcard nosuid nodev<br />
<br />
# We chown/chmod /data again so because mount is run as root + defaults<br />
mount ext2 /dev/block/mmcblk0p2 /data nosuid nodev<br />
chown system system /data<br />
chmod 0771 /data<br />
<br />
# Same reason as /data above<br />
chown system cache /cache<br />
chmod 0770 /cache<br />
<br />
# This may have been created by the recovery system with odd permissions<br />
chown system system /cache/recovery<br />
chmod 0770 /cache/recovery<br />
</pre><br />
<br />
===Compile===<br />
<pre class="host"><br />
$ cd $ANDROID_SOURCE<br />
$ make<br />
</pre><br />
<br />
==Making RootFS==<br />
===Android Root File system===<br />
Android emulator has 3 basic images on ''$ANDROID_SOURCE/tools/lib/images'' directory.<br />
* '''ramdisk.img''' is gziped cpio archive. ramdisk.img is a small partition image that is mounted read-only by the kernel at boot time. It only contains /init and a few config files. It is used to start init which will mount the rest of the system images properly and run the init procedure. A Ramdisk is a standard Linux feature. It is made just for the Android and do special things to start up the Android system.<br />
* '''system.img''' is a partition image that will be mounted as / and thus contains all system binaries.<br />
* '''userdata.img''' is a partition image that can be mounted as /data and thus contains all application-specific and user-specific data.<br />
<br />
===Create the Android root filesystem for apf27===<br />
Android’s root file system is generated in ''$ANDROID_SOURCE/out/target/product/generic''. We will create a folder containing all Android files images. <br />
<pre class="host"><br />
sudo rm -rf $ANDROID_SOURCE/rootfs/<br />
cd $ANDROID_SOURCE/out/target/product/generic<br />
mkdir $ANDROID_SOURCE/rootfs<br />
cp -a root/* $ANDROID_SOURCE/rootfs/<br />
cp -a system/* $ANDROID_SOURCE/rootfs/system/<br />
cd $ANDROID_SOURCE/rootfs<br />
sudo chown -R root.root .<br />
sudo chmod -R a+rwX data system<br />
</pre><br />
<br />
===JFFS2 Root file system===<br />
Actually, Android should use a file system how support mmap function like yaffs2, ext2 or ubifs. Unfortunaly, U-Boot support only jffs2 or ext2. So we will use ext2 on a µSD for data.<br />
====Prepare the MMC/µSD card====<br />
We will create two partitions on our mmc/µSD card, The first one will use for Android memory card, the second one will use for Android file system.<br />
First connect your card reader to your workstation, with the mmc/µSD card inside. Type the '''dmesg''' command to see which device is used by your workstation. Let’s assume that this device is '''/dev/sdb'''<br />
<pre class="host"><br />
$ dmesg<br />
...<br />
[ 9145.613954] sdb: sdb1 sdb2<br />
[ 9145.615125] sd 10:0:0:0: [sdc] Attached SCSI removable disk<br />
[ 9145.615258] sd 10:0:0:0: Attached scsi generic sg3 type 0<br />
</pre><br />
Type the mount command to check your currently mounted partitions. If MMC/SD partitions are mounted, unmount them.<br><br />
In a terminal edit partitions with fdisk:<br />
<pre class="host"><br />
sudo fdisk /dev/sdb<br />
</pre><br />
Delete any existing partition with the d command.<br><br />
Now, create the boot partition:<br />
<pre class="host"><br />
Command (m for help): n<br />
Command action<br />
e extended<br />
p primary partition (1-4)<br />
p<br />
Partition number (1-4): 1<br />
First cylinder (1-495, default 1): 1<br />
Last cylinder, +cylinders or +size{K,M,G} (1-239, default 239): +1G<br />
</pre><br />
Change its type to FAT32:<br />
<pre class="host"><br />
Command (m for help): t<br />
Selected partition 1<br />
Hex code (type L to list codes): c<br />
Changed system type of partition 1 to c (W95 FAT32 (LBA))<br />
</pre><br />
Using the n command again, create a second partition filling up the rest of your card (just accept default values).<br><br />
Now, format the partitions in your card:<br />
<pre class="host"><br />
sudo mkfs.vfat -n MemoryCard -F 32 /dev/sdb1<br />
sudo mkfs.ext2 -L data /dev/sdb2<br />
</pre><br />
====Boot setup====<br />
<pre class="host"><br />
$ sudo mkfs.jffs2 -n -e 0x20000 --pad=0x700000 -r $ANDROID_SOURCE/rootfs -o $TFTPBOOT/apf27-rootfs.arm.jffs2<br />
</pre><br />
The last thing left to do is to specify how the board boots Linux.<br><br />
In the U-boot prompt, make the mmc boot is on second partition of the mmc/µSD card<br />
<pre class="apf"> <br />
setenv addjffsargs 'setenv bootargs ${bootargs} root=/dev/mtdblock4 rootfstype=jffs2 init=/init'<br />
setenv bootcmd run mmcboot<br />
saveenv<br />
run update_kernel<br />
run update_rootfs<br />
</pre><br />
[[Image:Apf27_android.JPG]]<br />
<br />
==Debug==<br />
===Prerequisite===<br />
Installing the [http://developer.android.com/sdk/1.6_r1/installing.html Android Development Tools (ADT)]<br />
Trace with '''logcat''' with Eclipse-ADT<br />
<pre class="host"><br />
export ADBHOST=w.x.y.z<br />
adb kill-server<br />
adb start-server<br />
</pre><br />
<br />
===Test with Android emulator===<br />
Documentation on Android [http://developer.android.com/guide/developing/tools/emulator.html emulator]<br />
<pre class="host"><br />
cd $ANDROID_SOURCE/kernel<br />
make ARCH=arm goldfish_defconfig<br />
make ARCH=arm CROSS_COMPILE=$ANDROID_SOURCE/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi<br />
</pre><br />
Create AVD (Android Virtual Device)<br />
<pre class="host"><br />
$ANDROID_SDK/tools/android create avd -n APF27-H -t 4 -s 272x480<br />
$ANDROID_SDK/tools/android create avd -n APF27-L -t 4 -s 480x272<br />
$ANDROID_SOURCE/out/host/linux-x86/bin/emulator -avd APF27-H -sysdir $ANDROID_SOURCE/out/target/product/generic/ -kernel $ANDROID_SOURCE/kernel/arch/arm/boot/zImage -data $ANDROID_SOURCE/out/target/product/generic/userdata.img -ramdisk $ANDROID_SOURCE/out/target/product/generic/ramdisk.img -system $ANDROID_SOURCE/out/target/product/generic/system.img<br />
</pre><br />
<br />
==Links==<br />
* [http://elinux.org/Android Android page on elinux.org]<br />
** [http://elinux.org/Android_on_OMAP Android on OMAP portage page on elinux.org]<br />
* [http://wiki.openmoko.org/wiki/Android Android on OpenMoko]<br />
* http://wiki.kldp.org/wiki.php/AndroidPortingOnRealTarget<br />
<br />
==Thanks==<br />
Thanks to Xavier Romanens and Fabrice Carrel form Ecole d'ingénieurs et d'architectes de Fribourg for their contributions.</div>
BenjaminC