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 /> &lt;pre class=&quot;host&quot;&gt;<br /> sudo apt-get install uboot-mkimage mtd-utils<br /> &lt;/pre&gt;<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 /> &lt;pre class=&quot;config&quot;&gt;<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 /> &lt;/pre&gt;<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 /> &lt;pre class=&quot;host&quot;&gt;<br /> mkdir $ANDROID_SOURCE<br /> cd $ANDROID_SOURCE<br /> mkdir bin<br /> curl http://android.git.kernel.org/repo &gt;$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 /> &lt;/pre&gt;<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 /> &lt;pre class=&quot;host&quot;&gt;<br /> mkdir $ANDROID_KERNEL<br /> cd $ANDROID_KERNEL<br /> git clone git://android.git.kernel.org/kernel/common.git android-2.6.29<br /> &lt;/pre&gt;<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 /> &lt;pre class=&quot;host&quot;&gt;<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 /> &lt;/pre&gt;<br /> <br /> For generate the Linux kernel, we retrieve the default apf27 Linux configuration and modify it for start Android.<br /> &lt;pre class=&quot;host&quot;&gt;<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 /> &lt;/pre&gt;<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 /> &lt;pre class=&quot;config&quot;&gt;<br /> Device Drivers ---&gt;<br /> [*] Misc devices ---&gt;<br /> [*] Android pmem allocator<br /> &lt;/pre&gt;<br /> * Activate the Android drivers<br /> &lt;pre class=&quot;config&quot;&gt;<br /> Device Drivers ---&gt;<br /> [*] Staging drivers ---&gt; <br /> [ ] Exclude Staging drivers from being built (NEW)<br /> ...<br /> Android ---&gt;<br /> [*] Android Drivers<br /> [*] Android Binder IPC Driver<br /> &lt;*&gt; Android log driver <br /> [ ] Android RAM buffer console<br /> [*] Timed output class driver (NEW)<br /> &lt; &gt; Android timed gpio driver (NEW)<br /> [*] Android Low Memory Killer <br /> &lt;/pre&gt;<br /> * Activate the Anonymous Shared Memory Subsystem<br /> &lt;pre class=&quot;config&quot;&gt;<br /> General setup ---&gt;<br /> [*] Enable the Anonymous Shared Memory Subsystem<br /> &lt;/pre&gt;<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 /> &lt;pre class=&quot;config&quot;&gt;<br /> Power management options ---&gt;<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) ---&gt;<br /> (X) Sysfs interface <br /> ...<br /> Device Drivers ---&gt;<br /> Input device support ---&gt;<br /> [*] Touchscreens ---&gt;<br /> &lt;*&gt; TSC 2102 based touchscreens<br /> ...<br /> &lt;*&gt; Hardware Monitoring support ---&gt;<br /> &lt;/pre&gt;<br /> ===Audio kernel configuration===<br /> * Include in the compiled kernel the audio driver<br /> &lt;pre class=&quot;config&quot;&gt;<br /> Device Drivers ---&gt;<br /> &lt;*&gt; Sound card support ---&gt;<br /> --- Sound card support<br /> &lt;*&gt; Advanced Linux Sound Architecture ---&gt;<br /> [*] ARM sound devices ---&gt;<br /> --- ARM sound <br /> &lt;*&gt; i.MX27 SSI driver<br /> &lt;*&gt; TSC210x alsa driver<br /> &lt;/pre&gt;<br /> ===Modify touchscreen driver===<br /> Android don't use tslib library so we should add the calibration directly in ts drivers&lt;br&gt;<br /> edit ''$ANDROID_KERNEL/drivers/input/touchscreen/tsc2102_ts.c''&lt;br&gt;<br /> Add new definitions for X and Y ranges<br /> &lt;source lang=&quot;c&quot;&gt;<br /> #define DRIVER_NAME &quot;TSC210x Touchscreen&quot;<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 /> &lt;/source&gt;<br /> Send touch event to Android when the user release the touchscreen<br /> &lt;source lang=&quot;c&quot;&gt;<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 /> &lt;/source&gt;<br /> &lt;source lang=&quot;c&quot;&gt;<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 &lt;&lt; 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 /> &lt;/source&gt;<br /> Calibrate the touchscreen with X and Y ranges<br /> &lt;source lang=&quot;c&quot;&gt;<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-&gt;name = DRIVER_NAME;<br /> dev-&gt;dev.parent = &amp;pdev-&gt;dev;<br /> dev-&gt;evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);<br /> dev-&gt;keybit[BIT_WORD(BTN_TOUCH)] |= BIT_MASK(BTN_TOUCH);<br /> dev-&gt;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 &quot;Unable to register TSC210x as input device !\n&quot;);<br /> goto error;<br /> }<br /> <br /> printk(DRIVER_NAME &quot; driver initialized\n&quot;);<br /> return 0;<br /> <br /> error:<br /> input_free_device(dev);<br /> return status;<br /> }<br /> &lt;/source&gt;<br /> ===Build Android kernel===<br /> Compile the kernel and generate image kernel for U-Boot Loader<br /> &lt;pre class=&quot;host&quot;&gt;<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 /> &lt;/pre&gt;<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 /> &lt;source lang=&quot;c&quot;&gt;<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 -&gt; true */<br /> /*!!!comment out!!!<br /> if (readFromFile(path, buf, SIZE) &gt; 0) {<br /> if (buf[0] == '1') {<br /> value = true;<br /> }<br /> }<br /> */<br /> env-&gt;SetBooleanField(obj, fieldID, value);<br /> }<br /> &lt;/source&gt;<br /> *Change the volume, voltage and temperature of battery. Return 100%.<br /> &lt;source lang=&quot;c&quot;&gt;<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 -&gt; 100 */<br /> /*!!!comment out!!!<br /> if (readFromFile(path, buf, SIZE) &gt; 0) {<br /> value = atoi(buf);<br /> }<br /> */<br /> env-&gt;SetIntField(obj, fieldID, value);<br /> }<br /> &lt;/source&gt;<br /> * Change the battery charged status as full and deterioration status as fair.<br /> &lt;source lang=&quot;c&quot;&gt;<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-&gt;SetIntField(obj, gFieldIds.mBatteryStatus, gConstants.statusFull);<br /> env-&gt;SetIntField(obj, gFieldIds.mBatteryHealth, gConstants.healthGood);<br /> env-&gt;SetObjectField(obj, gFieldIds.mBatteryTechnology, env-&gt;NewStringUTF(&quot;1&quot;));<br /> <br /> /*!!!comment out!!!<br /> const int SIZE = 128;<br /> char buf[SIZE];<br /> <br /> if (readFromFile(BATTERY_STATUS_PATH, buf, SIZE) &gt; 0)<br /> env-&gt;SetIntField(obj, gFieldIds.mBatteryStatus, getBatteryStatus(buf));<br /> <br /> if (readFromFile(BATTERY_HEALTH_PATH, buf, SIZE) &gt; 0)<br /> env-&gt;SetIntField(obj, gFieldIds.mBatteryHealth, getBatteryHealth(buf));<br /> <br /> if (readFromFile(BATTERY_TECHNOLOGY_PATH, buf, SIZE) &gt; 0)<br /> env-&gt;SetObjectField(obj, gFieldIds.mBatteryTechnology, env-&gt;NewStringUTF(buf));<br /> */<br /> }<br /> &lt;/source&gt;<br /> <br /> ===Audio===<br /> For activate the audio, we should retrieve Alsa android module whose not directly add in the source<br /> &lt;pre class=&quot;host&quot;&gt;<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 /> &lt;/pre&gt;<br /> <br /> edit ''$ANDROID_SOURCE/build/target/board/generic/BoardConfig.mk'' and modify the audio divers used by Android<br /> &lt;pre class=&quot;config&quot;&gt; <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 /> &lt;/pre&gt;<br /> <br /> edit ''$ANDROID_SOURCE/hardware/alsa_sound/AudioHardwareALSA.cpp'' and change bufferSize to 8192 in twice StreamDefaults structures &lt;br&gt;<br /> edit ''$ANDROID_SOURCE/system/core/init/devices.c'' and add audio device in Linux devices<br /> &lt;source lang=&quot;c&quot;&gt;<br /> static struct perms_ devperms[] = {<br /> { &quot;/dev/null&quot;, 0666, AID_ROOT, AID_ROOT, 0 },<br /> ...<br /> { &quot;/dev/qmi1&quot;, 0640, AID_RADIO, AID_RADIO, 0 },<br /> { &quot;/dev/qmi2&quot;, 0640, AID_RADIO, AID_RADIO, 0 },<br /> // Add this line<br /> { &quot;/dev/snd/&quot;, 0664, AID_SYSTEM, AID_AUDIO, 1 },<br /> { NULL, 0, 0, 0, 0 },<br /> };<br /> &lt;/source&gt;<br /> <br /> &lt;source lang=&quot;c&quot;&gt;<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-&gt;subsystem, &quot;mtd&quot;, 3)) {<br /> base = &quot;/dev/mtd/&quot;;<br /> mkdir(base, 0755);<br /> // add this conditionnal block<br /> } else if(!strncmp(uevent-&gt;subsystem, &quot;sound&quot;, 5)) {<br /> base = &quot;/dev/snd/&quot;;<br /> mkdir(base, 0755);<br /> } else if(!strncmp(uevent-&gt;subsystem, &quot;misc&quot;, 4) &amp;&amp;<br /> !strncmp(name, &quot;log_&quot;, 4)) {<br /> base = &quot;/dev/log/&quot;;<br /> mkdir(base, 0755);<br /> name += 4;<br /> } else<br /> base = &quot;/dev/&quot;;<br /> }<br /> &lt;/source&gt;<br /> Add audio files in Android files system<br /> &lt;pre class=&quot;host&quot;&gt;<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 /> &lt;/pre&gt;<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 /> &lt;pre class=&quot;config&quot;&gt;<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 /> &lt;/pre&gt;<br /> <br /> ===Compile===<br /> &lt;pre class=&quot;host&quot;&gt;<br /> $ cd $ANDROID_SOURCE<br /> $ make<br /> &lt;/pre&gt;<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 /> &lt;pre class=&quot;host&quot;&gt;<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 /> &lt;/pre&gt;<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 /> &lt;pre class=&quot;host&quot;&gt;<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 /> &lt;/pre&gt;<br /> Type the mount command to check your currently mounted partitions. If MMC/SD partitions are mounted, unmount them.&lt;br&gt;<br /> In a terminal edit partitions with fdisk:<br /> &lt;pre class=&quot;host&quot;&gt;<br /> sudo fdisk /dev/sdb<br /> &lt;/pre&gt;<br /> Delete any existing partition with the d command.&lt;br&gt;<br /> Now, create the boot partition:<br /> &lt;pre class=&quot;host&quot;&gt;<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 /> &lt;/pre&gt;<br /> Change its type to FAT32:<br /> &lt;pre class=&quot;host&quot;&gt;<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 /> &lt;/pre&gt;<br /> Using the n command again, create a second partition filling up the rest of your card (just accept default values).&lt;br&gt;<br /> Now, format the partitions in your card:<br /> &lt;pre class=&quot;host&quot;&gt;<br /> sudo mkfs.vfat -n MemoryCard -F 32 /dev/sdb1<br /> sudo mkfs.ext2 -L data /dev/sdb2<br /> &lt;/pre&gt;<br /> ====Boot setup====<br /> &lt;pre class=&quot;host&quot;&gt;<br /> $ sudo mkfs.jffs2 -n -e 0x20000 --pad=0x700000 -r $ANDROID_SOURCE/rootfs -o $TFTPBOOT/apf27-rootfs.arm.jffs2<br /> &lt;/pre&gt;<br /> The last thing left to do is to specify how the board boots Linux.&lt;br&gt;<br /> In the U-boot prompt, make the mmc boot is on second partition of the mmc/µSD card<br /> &lt;pre class=&quot;apf&quot;&gt; <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 /> &lt;/pre&gt;<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 /> &lt;pre class=&quot;host&quot;&gt;<br /> export ADBHOST=w.x.y.z<br /> adb kill-server<br /> adb start-server<br /> &lt;/pre&gt;<br /> <br /> ===Test with Android emulator===<br /> Documentation on Android [http://developer.android.com/guide/developing/tools/emulator.html emulator]<br /> &lt;pre class=&quot;host&quot;&gt;<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 /> &lt;/pre&gt;<br /> Create AVD (Android Virtual Device)<br /> &lt;pre class=&quot;host&quot;&gt;<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 /> &lt;/pre&gt;<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