IGEPv2 and Android Froyo: Build from scratch

Requirements:

Android Froyo (2.2) sources (you might also want to go to the android websites

SDK and NDK

Android sources

IGEPv2

Ubuntu 8.04 or 11.04 (I didn’t tests on other versions, but it should be pretty close)

I had to use the serial port on the IGEP board and unfortunately I wasn’t able to modify from the terminal emulator in Android the kernel so that the J960 connector is setup as a RS232 instead of a RS485.

So I pretty much had to recompile the whole thing from scratch and setup the RS232 serial port from the config file right before building. This was pretty painful for several reasons:

  1. I never did that, and it took me several days to do a succesfull build and then mount it on the sd card.
  2. I realized afterwards that I should have used adb. I didn’t at first because the web page of Vladistan explicitly says that one needs to root his device in order to successfuly use his library. This may be true for devices such as smartphones or tablets but it’s not true for the custom built Android I guess.
  3. the build was a pain mainly because of the first part:  the download with Git. I had several connection hanging for quite a while and the first succesful pull took me about 6 to 7 hours, and I had to resume the download a lot (that means ctrl+c and then repo sync). This happened because I didn’t give enough memory to my VM, 500 Mb to 1Gb, and setting it to 2 Gb or higher should resolve the problem.
  4. the script provided by IGEP to create the SDCard didn’t work for me, with several configurations (Macbook host for the VM + Internal SD Card reader, PC-Red Hat host for the VM + Internal SD Card reader, Macbook host for the VM + External SD Card reader, PC-Red Hat host for the VM + External SD Card reader) so I just had to find another way.
  5. after the first successful build, i managed to get the RS232 port working but Android just froze after several seconds or user interactions… After quite a search, I found a patch which is correcting the binder in the android kernel. See below for more infos.

Below are the instructions provided mostly by the IGEP wiki for Froyo and the IGEPv2 board. I added and modified several lines to make it less painful for you to copy paste the commands in the terminal if you need to. Those may change in the near future, so you should read both ISEE’s (and my instructions.

NOTE: I assume that you stored all related files in ~/Desktop/Files . If not, simply change the directory paths.

Development environment

In order to do a successful build, you are gonna have to download a few packages and use java 5 (that’s only Froyo and below if I remember correctly, if you need gingerbread or above use java 6). Copy past the script below to a <file_name>.sh file and make executable (chmod a+x <file_name>.sh). Then just type <file_name>.sh

If you are building with 8.04, you might have to use the

deb http://us.archive.ubuntu.com/ubuntu/ jaunty multiverse
deb http://us.archive.ubuntu.com/ubuntu/ jaunty-updates multiverse

repositories instead of the ones listed below.

Say no when the dpkg-reconfigure GUI menu asks you.

#!/bin/sh

sudo dpkg-reconfigure dash
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 git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev libc6-dev libncurses5-dev x11proto-core-dev libx11-dev libreadline5-dev libz-dev libgl1-mesa-dev sun-java5-jdk git-core gnupg expect flex bison gperf libsdl-dev libesd0-dev libwxgtk2.6-dev build-essential zip curl libncurses5-dev zlib1g-dev libreadline5-dev realpath coreutils valgrind uboot-mkimage
sudo update-java-alternatives -s java-1.5.0-sun

Getting sources

Android uses the repo tool to manages the code. As I understand, Google developed it on top of git. Use the script below. It will create the sources directory under ~/bin/froyo and download the repo tool. You’re gonna have to enter your name and email before you can actually start downloading the sources.

#!/bin/sh

mkdir ~/bin
curl http://android.git.kernel.org/repo >~/bin/repo
chmod a+x ~/bin/repo
export PATH=$PATH:~/bin
export LANG=C

mkdir ~/bin/froyo
cd ~/bin/froyo
repo init -u git://gitorious.org/rowboat/manifest.git -m rowboat-froyo-dsp.xml

Now that the repo tool is initialized, let’s start downloading. You can remove the -j4 parameter if you don’t want parallel downloads.

cd ~/bin/froyo
repo sync -j4

Install Texas Instruments and IGEPs files

This past is mostly targeted for the DM3730 chip which is on the IGEPv2 board and IGEP targeted config and linux kernel files.

You are gonna have to register with TI website in order to get the dvsdk and go to the IGEP Froyo wiki to download the related files.

Put them in ~/Desktop/Files/ when you are done and run the script below.

  • Patch 4 :

diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index 99010d4..0e304d5 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -32,6 +32,8 @@
 #include <linux/uaccess.h>
 #include <linux/vmalloc.h>

+#include <linux/kthread.h>
+
 #include "binder.h"

 static DEFINE_MUTEX(binder_lock);
@@ -47,6 +49,9 @@ static struct binder_node *binder_context_mgr_node;
 static uid_t binder_context_mgr_uid = -1;
 static int binder_last_id;

+static struct task_struct *binder_deferred_task;
+static DECLARE_WAIT_QUEUE_HEAD(binder_deferred_wq);
+
 static int binder_read_proc_proc(char *page, char **start, off_t off,
 				 int count, int *eof, void *data);

@@ -3050,14 +3055,23 @@ static void binder_deferred_release(struct binder_proc *proc)
 	kfree(proc);
 }

-static void binder_deferred_func(struct work_struct *work)
+static int binder_deferred_thread(void *ignore)
 {
 	struct binder_proc *proc;
 	struct files_struct *files;
-
+	int ret;
 	int defer;
-	do {
+
+	for (;;) {
+
+		do {
+			ret = wait_event_interruptible(binder_deferred_wq, !hlist_empty(&binder_deferred_list));
+		} while (ret == -ERESTARTSYS);
+		if (kthread_should_stop())
+			break;
+
 		mutex_lock(&binder_lock);
+
 		mutex_lock(&binder_deferred_lock);
 		if (!hlist_empty(&binder_deferred_list)) {
 			proc = hlist_entry(binder_deferred_list.first,
@@ -3072,36 +3086,42 @@ static void binder_deferred_func(struct work_struct *work)
 		mutex_unlock(&binder_deferred_lock);

 		files = NULL;
-		if (defer & BINDER_DEFERRED_PUT_FILES) {
-			files = proc->files;
-			if (files)
-				proc->files = NULL;
-		}

-		if (defer & BINDER_DEFERRED_FLUSH)
-			binder_deferred_flush(proc);
+		if (proc != NULL) {
+
+			if (defer & BINDER_DEFERRED_PUT_FILES) {
+				files = proc->files;
+				if (files)
+					proc->files = NULL;
+			}
+
+			if (defer & BINDER_DEFERRED_FLUSH)
+				binder_deferred_flush(proc);

-		if (defer & BINDER_DEFERRED_RELEASE)
-			binder_deferred_release(proc); /* frees proc */
+			if (defer & BINDER_DEFERRED_RELEASE)
+				binder_deferred_release(proc); /* frees proc */
+		}

 		mutex_unlock(&binder_lock);
+
 		if (files)
 			put_files_struct(files);
-	} while (proc);
+
+	}
+
+	return 0;
 }
-static DECLARE_WORK(binder_deferred_work, binder_deferred_func);

 static void
 binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer)
 {
 	mutex_lock(&binder_deferred_lock);
 	proc->deferred_work |= defer;
-	if (hlist_unhashed(&proc->deferred_work_node)) {
+	if (hlist_unhashed(&proc->deferred_work_node))
 		hlist_add_head(&proc->deferred_work_node,
 				&binder_deferred_list);
-		schedule_work(&binder_deferred_work);
-	}
 	mutex_unlock(&binder_deferred_lock);
+	wake_up_interruptible(&binder_deferred_wq);
 }

 static char *print_binder_transaction(char *buf, char *end, const char *prefix,
@@ -3759,6 +3779,12 @@ static int __init binder_init(void)
 				       binder_read_proc_transaction_log,
 				       &binder_transaction_log_failed);
 	}
+
+	if (ret == 0) {
+		binder_deferred_task = kthread_run(binder_deferred_thread, NULL, "binder_deferred_thread");
+		if (binder_deferred_task == NULL)
+			ret = PTR_ERR(binder_deferred_task);
+	}
 	return ret;
 }
  • Patch 5 :

diff --git a/tasks/fake-ts/Android.mk b/tasks/fake-ts/Android.mk
new file mode 100644
index 0000000..27a9298
--- /dev/null
+++ b/tasks/fake-ts/Android.mk
@@ -0,0 +1,29 @@
+# Copyright (C) 2011 Linaro Ltd.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+ifneq ($(TARGET_SIMULATOR),true)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := faketsd
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := fake-ts.c
+LOCAL_PRELINK_MODULE := false
+
+include $(BUILD_EXECUTABLE)
+
+endif # !TARGET_SIMULATOR
diff --git a/tasks/fake-ts/fake-ts.c b/tasks/fake-ts/fake-ts.c
new file mode 100644
index 0000000..b5ec551
--- /dev/null
+++ b/tasks/fake-ts/fake-ts.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2009 0xlab - http://0xlab.org/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ */
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <linux/uinput.h>
+
+/* look up source file system/core/init/devices.c for exact node */
+#define UINPUT_DEV "/dev/uinput"
+
+#define DEV_NAME "Fake Touchscreen"
+
+static int uinput_fd = 0;
+
+static void uinput_touch_init(const char* uinput_dev,
+                              const char* dev_name)
+{
+    struct uinput_user_dev dev;
+
+    uinput_fd = open(uinput_dev, O_WRONLY);
+    if (uinput_fd <= 0) {
+        perror("Error opening uinput device.\n");
+        return;
+    }
+    memset(&dev, 0, sizeof(dev));
+    strcpy(dev.name, dev_name);
+    write(uinput_fd, &dev, sizeof(dev));
+
+    /* touch screen event */
+    ioctl(uinput_fd, UI_SET_EVBIT, EV_ABS);
+    ioctl(uinput_fd, UI_SET_ABSBIT, ABS_X);
+    ioctl(uinput_fd, UI_SET_ABSBIT, ABS_Y);
+    ioctl(uinput_fd, UI_SET_EVBIT, EV_KEY);
+    ioctl(uinput_fd, UI_SET_KEYBIT, BTN_TOUCH);
+
+    /* register userspace input device */
+    ioctl(uinput_fd, UI_DEV_CREATE, 0);
+}
+
+static void uinput_touch_deinit()
+{
+    if (uinput_fd > 0) {
+        close(uinput_fd);
+    }
+}
+
+int main(int argc, char* argv[])
+{
+    uinput_touch_init(UINPUT_DEV, DEV_NAME);
+
+    while (1) {
+        sleep(60);
+    }
+
+    uinput_touch_deinit();
+
+    return 0;
+}
+
  • Script :

#!/bin/sh
	## first param is usually ~/bin
	## second param is usually ~/Desktop/Files
	if [ $# -ne 2 ]
		then
			echo "Using defaults"
			ANDSOURCES=~/bin
			FILES=~/Desktop/Files
		else
			ANDSOURCES=$1
			FILES=$2
		fi
			START=$(date +"%T")
			echo "Using android sources in $ANDSOURCES, and additional files in $FILES"
			export LANG=C

			echo "PATCHING"
			cd $ANDSOURCES/froyo/device/ti/igepv2
			patch -b < $FILES/patch1

			cd $ANDSOURCES/froyo/external/wpa_supplicant
			patch -b < $FILES/patch2

			cd $ANDSOURCES/froyo/hardware/libhardware_legacy/wifi
			patch -b < $FILES/patch3

			mkdir -p $ANDSOURCES/froyo/device/ti/igepv2/libertas/
			cp $FILES/rc.libertas $ANDSOURCES/froyo/device/ti/igepv2/libertas/

			cd $ANDSOURCES/froyo/kernel/drivers/staging/android/
			patch -b < $FILES/patch4

			cd $ANDSOURCES/froyo/build/core/
			patch -b < $FILES/patch5

			mkdir -p $ANDSOURCES/froyo/device/ti/igepv2/libertas/
			cd $ANDSOURCES/froyo/device/ti/igepv2/libertas/
			wget http://downloads.igep.es/android/froyo-2.2/libertas.ko
			wget http://downloads.igep.es/android/froyo-2.2/libertas_sdio.ko

			mkdir -p $ANDSOURCES/froyo/device/ti/igepv2/firmware/
			cd $ANDSOURCES/froyo/device/ti/igepv2/firmware/
			wget http://downloads.igep.es/android/froyo-2.2/sd8686.bin
			wget http://downloads.igep.es/android/froyo-2.2/sd8686_helper.bin

			echo "INSTALLING TI"
			echo "cp $FILES/dvsdk_dm3730-evm_4_01_00_09 $ANDSOURCES/froyo/external/ti-dsp"
			cp $FILES/dvsdk_dm3730-evm_4_01_00_09_setuplinux $ANDSOURCES/froyo/external/ti-dsp
			export LANG=C
			export OMAPES=5.x
			cd $ANDSOURCES/froyo
			external/ti-dsp/./get_tidsp.sh

			echo "INSTALLING IGEP ADDS"
			cd $ANDSOURCES/froyo/kernel
			git remote add igep git://git.igep.es/pub/scm/linux-omap-2.6.git
			git fetch igep
			git checkout igep/linux-2.6.32.y-android -b linux-2.6.32.y-android

			echo "install.sh STARTED AT $NOW"
			END=$(date +"%T")
			echo "AND ENDED AT $END"

Let’s build

cd ~/bin/froyo
source build/envsetup.sh
lunch igepv2-eng
make TARGET_PRODUCT=igepv2 -j8 OMAPES=5.x

 

Create SD Card

You should follow the tutorials below to format your SD Card and to copy the files on it so that you can boot Android.

Format the SD Card

Setup SD Card with Android

NOTE: I used the board to create the partition table, and then I used my Macbook to format and mount the files.

Below is the boot.source script which I use (with debug console).

mmc init 0

fatload mmc 0 80200000 uImage

setenv bootargs ‘mem=71M@0x80000000 mem=384M@0x88000000 console=tty0 console=ttyS2,115200n8 \

androidboot.console=ttyS2 root=/dev/mmcblk0p2 rw rootfstype=ext3 init=/init rootwait ip=off \

omap_vout.vid1_static_vrfb_alloc=y omapfb.mode=dvi:1280x720MR-16 mpurate=1000’

bootm 0x80200000

You can use the script below to facilitate the process. The script copies each build files to a directory called ~/Desktop/Files/build<time_of_day>/

#!/bin/sh
	if [ $# -eq 2 ]; then                   
			ANDSOURCES=$1
			DEVICE=$2	    	
	elif [ $# -eq 1 ]; then
			echo "Using defaults"
			ANDSOURCES=~/bin
			DEVICE=/dev/sdb	
			MKCARD=$1		
	fi
FILES=~/Desktop/Files
echo "Creating tarball"
now=$(date +"%T")
stri=$(date "+-%Y-%m-%d-")"$now"
mkdir -p $ANDSOURCES/froyo/froyo-rootfs
cp -r $ANDSOURCES/froyo/out/target/product/igepv2/root/* $ANDSOURCES/froyo/froyo-rootfs
cp -r $ANDSOURCES/froyo/out/target/product/igepv2/system $ANDSOURCES/froyo/froyo-rootfs
cd $ANDSOURCES/froyo
sudo $ANDSOURCES/froyo/build/tools/mktarball.sh $ANDSOURCES/froyo/out/host/linux-x86/bin/fs_get_stats froyo-rootfs . rootfs froyo-rootfs.tar.bz2
mkdir -p $FILES/build"$stri"/
cp $ANDSOURCES/froyo/froyo-rootfs.tar.bz2 $FILES/build"$stri"/
cp $ANDSOURCES/froyo/kernel/arch/arm/boot/uImage $FILES/build"$stri"/

if [ $1 -eq 1 ]; then 
	echo "Formatting the SD Card"
	sudo umount "$DEVICE"1 
	sudo umount "$DEVICE"2 
	sudo mkfs.msdos -F 32 "$DEVICE"1 -n BOOT
	sudo mkfs.ext3 -L ROOTFS "$DEVICE"2

	echo "Copying system files"
	sudo mkdir -p /mnt/fat32
	sudo mount "$DEVICE"1 /mnt/fat32
	sudo cp $ANDSOURCES/froyo/kernel/arch/arm/boot/uImage /mnt/fat32

	sudo mkdir -p /mnt/ext3
	sudo mount "$DEVICE"2 /mnt/ext3
	sudo tar jxfv $ANDSOURCES/froyo/froyo-rootfs.tar.bz2 --numeric-owner -C /mnt/ext3
	sync

	echo "Unmounting"
	sudo umount /mnt/fat32
	sudo umount /mnt/ext3
else
	echo "Not making SDCARD" 
fi

3 thoughts on “IGEPv2 and Android Froyo: Build from scratch

  1. Dorthy

    I just wanted to just take a few moments and inform
    you that I really liked the article. I frankly don’t think that generally people know the level of hard work that goes into producing a good webpage. I am sure that this will be kind of random nevertheless it really bugs me occasionally. Nonetheless fantastic site.

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s