Embedded Linux Encounters

A peek in to the world of Embedded Linux and stuff

  • Linux is addictive, I'm hooked!

         Geek@WastingTime>

PXAFB Android Patch

Posted by Vaisakh P S On 8:10 PM 0 comments

PXA Frame Buffer driver Patch for Android - http://androidzaurus.seesaa.net/article/105551643.html


Great work by the Ando.

During booting of kernel, these are the possible error messages that may show. Here are the reasons for the same:

Kernel completely up but console is not shown
  • This could have been because of various reasons. Either the console device specified in boot arguments would be different
  • There might not be a device instance corresponding to the specified device under /dev directory.

Init not found or Failure in executing init
  • Init program might not be given execution privileges or root might not be the owner of the init executable.
  • If BusyBox is not compiled as a static binary, then failure in loading the dynamic libraries can also result this error.


Failed in mounting root file system
  • The device such as MMC card or USB will require certain amount time to be made accessible or mounted. So use the 'rootdelay' boot argument to introduce a delay before kernel tries to mount the file system.
  • If the file system is corrupted then also this error would come up. So it is advisable to maintain a back up file system image to re-flash your storage if this happens.
  • Periodically run a fsck command on the file systems used including root file system.

Porting Android

Posted by Vaisakh P S On 7:54 PM 1 comments

Android build system by default generates few YAFF2 File system Images, which can be flashed on devices running in NAND flash. Since the platform which I was working on did not have a NAND flash on board. The images had be made available to Kernel in some other storage devices like NOR flash, SDCARD or USB Memory Stick.


There will be three out put images of the build process:
  • Root - A small image in order kilo bytes, with basic utilities and init script to bring rest of the system up.
  • System - Contains the Android specific programs and related libraries. The size will be some where around 40 to 50 Mega Bytes (for default configuration) depending on the build configuration.
  • Data - Will be a blank file system initially, but as system boots up, relevant information will added.
Like every other Linux Root file system image, there is an init script, (format is different from standard init script). Here comment out of the portion of script which mounts the yaffs2 file system like this:
#mount yaffs2 mtd@system /system
#mount yaffs2 mtd@system /system ro remount
#mount yaffs2 mtd@userdata /data nosuid nodev

For bringing up the required file system, an SDCARD base storage system was decided. The sdcard was partitioned in to four ext2 partitions. Here is the partition layout
Partition #1 : Root file system generated from BuildRoot
Partition #2 : Root file system generated from Android
Partition #3 : System partitions generated from Android
Partition #4 : Data partition to be used to Android.

The Linux system was be booted up with Partition#1 as root. Then Partitions 2, 3 and 4 are mounted like this
mount /dev/mmcblk0p2 /media/mmc
mount /dev/mmcblk0p3 /media/mmc/system
mount /dev/mmcblk0p4 /media/mmc/data
Using the 'chroot' command the root will be changed to Partition#2 hence initiating startup of Android:
chroot /media/mmc /init
NOTE

  • Ensure that the system and data directories are given global read, write and execute permission.
  • To interface touch screen with Android, make use modifications in Android Input System code to make use of the calibration corrections obtained using TsLib. (Refer previous post)

AT91SAM9g24 Board that was provided for hands-on





AT91SAM9g24 Board running MatchBox Window Manager

Making TsLib work in Android

Posted by Vaisakh P S On 7:47 AM 0 comments


For my initial porting of Android, I had to work on a PXA270 board with a WM9713 Codec IC. So here are the steps that I followed to make touch screen working properly. Initially, touchscreen values were not accepting properly by Android even though ts_calibrate and ts_test were working properly.

Modifying Touch Drivers
Modify the WM97XX and WM9713 driver to report pen down event properly to the event system.
diff --git a/drivers/input/touchscreen/wm9713.c b/drivers/input/touchscreen/wm9713.c
index 781ee83..055db86 100644
--- a/drivers/input/touchscreen/wm9713.c
+++ b/drivers/input/touchscreen/wm9713.c
@@ -14,6 +14,7 @@
* option) any later version.
*
*/
+#define DEBUG

#include

#include

@@ -54,7 +55,7 @@ MODULE_PARM_DESC(rpu, "Set internal pull up resitor for pen detect.");
* This is used to increase the range of values returned by the adc
* when measureing touchpanel pressure.
*/
-static int pil;
+static int pil = 1;
module_param(pil, int, 0);
MODULE_PARM_DESC(pil, "Set current used for pressure measurement.");

@@ -395,7 +396,6 @@ err:
static int wm9713_poll_touch(struct wm97xx *wm, struct wm97xx_data *data)
{
int rc;
-
if (coord) {
rc = wm9713_poll_coord(wm, data);
if (rc != RC_VALID)


diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c
index d589ab0..6859078 100644
--- a/drivers/input/touchscreen/wm97xx-core.c
+++ b/drivers/input/touchscreen/wm97xx-core.c
@@ -34,7 +34,7 @@
* - Support for async sampling control for noisy LCDs.
*
*/
-
+#define DEBUG
#include

#include

#include

@@ -392,7 +392,8 @@ static int wm97xx_init_pen_irq(struct wm97xx *wm)

return 0;
}

static int wm97xx_read_samples(struct wm97xx *wm)
{
struct wm97xx_data data;
@@ -410,6 +411,7 @@ static int wm97xx_read_samples(struct wm97xx *wm)
wm->pen_is_down = 0;
dev_dbg(wm->dev, "pen up\n");
input_report_abs(wm->input_dev, ABS_PRESSURE, 0);
+ input_report_key(wm->input_dev, BTN_TOUCH, wm->pen_is_down);
input_sync(wm->input_dev);
} else if (!(rc & RC_AGAIN)) {
/* We need high frequency updates only while
@@ -427,13 +429,30 @@ static int wm97xx_read_samples(struct wm97xx *wm)
}

} else if (rc & RC_VALID) {
input_report_abs(wm->input_dev, ABS_X, data.x & 0xfff);
input_report_abs(wm->input_dev, ABS_Y, data.y & 0xfff);
input_report_abs(wm->input_dev, ABS_PRESSURE, data.p & 0xfff);
+ wm->pen_is_down = 1;
+ input_report_key(wm->input_dev, BTN_TOUCH, wm->pen_is_down);
input_sync(wm->input_dev);
wm->pen_is_down = 1;
wm->ts_reader_interval = wm->ts_reader_min_interval;
@@ -630,9 +649,11 @@ static int wm97xx_probe(struct device *dev)
wm->input_dev->open = wm97xx_ts_input_open;
wm->input_dev->close = wm97xx_ts_input_close;
set_bit(EV_ABS, wm->input_dev->evbit);
+ set_bit(EV_KEY, wm->input_dev->evbit);
set_bit(ABS_X, wm->input_dev->absbit);
set_bit(ABS_Y, wm->input_dev->absbit);
set_bit(ABS_PRESSURE, wm->input_dev->absbit);
+ set_bit(BTN_TOUCH, wm->input_dev->keybit);
input_set_abs_params(wm->input_dev, ABS_X, abs_x[0], abs_x[1],
abs_x[2], 0);
input_set_abs_params(wm->input_dev, ABS_Y, abs_y[0], abs_y[1],


Use TsLib
Compile tslib using buildroot or something else and run it on the board with the parameters set:
export TSLIB_CONSOLEDEVICE=none
export TSLIB_FBDEVICE=/dev/fb0
export TSLIB_TSDEVICE=/dev/event0
export TSLIB_CALIBFILE=/etc/pointercal
export TSLIB_CONFFILE=/etc/ts.conf
export TSLIB_PLUGINDIR=/usr/lib/ts

After running ts_calibrate you will obtain 'pointercal' file with the corrections that needed to be applied for touchscreen values.






Modify Kernel Code
Change the kernel configuration to enable the following functionalities:

# Power management options
#
CONFIG_PM=y
CONFIG_PM_DEBUG=y
CONFIG_PM_VERBOSE=y
CONFIG_CAN_PM_TRACE=y
CONFIG_PM_SLEEP=y
CONFIG_SUSPEND=y
CONFIG_PM_TEST_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
CONFIG_HAS_WAKELOCK=y
CONFIG_HAS_EARLYSUSPEND=y
CONFIG_WAKELOCK=y
CONFIG_WAKELOCK_STAT=y
CONFIG_USER_WAKELOCK=y
CONFIG_EARLYSUSPEND=y

CONFIG_ANDROID_PMEM=y
CONFIG_ANDROID_TIMED_GPIO=y
CONFIG_BINDER_IPC=y

CONFIG_LOW_MEMORY_KILLER=y
CONFIG_LOGGER=y
CONFIG_ANDROID_RAM_CONSOLE=y
CONFIG_ANDROID_RAM_CONSOLE_ENABLE_VERBOSE=y
Modify Android Code
Apply the following patch to the Android Input management code. Copy the pointrecal file that you obtained from ts_calibrate to /system/etc/pointrecal
diff --git a/services/java/com/android/server/InputDevice.java b/services/java/com/android/server/InputDevice.java
index 6eb6242..f1ed013 100644
--- a/services/java/com/android/server/InputDevice.java
+++ b/services/java/com/android/server/InputDevice.java
@@ -22,6 +22,9 @@ import android.view.MotionEvent;
import android.view.Surface;
import android.view.WindowManagerPolicy;

+import java.io.FileInputStream;
+import java.util.StringTokenizer;
+
public class InputDevice {
static final boolean DEBUG_POINTERS = false;
static final boolean DEBUG_HACKS = false;
@@ -29,8 +32,10 @@ public class InputDevice {
/** Amount that trackball needs to move in order to generate a key event. */
static final int TRACKBALL_MOVEMENT_THRESHOLD = 6;

+ static final String CALIBRATION_FILE = "/system/etc/pointercal";
+
/** Maximum number of pointers we will track and report. */
- static final int MAX_POINTERS = 10;
+ static final int MAX_POINTERS = 2;

final int id;
final int classes;
@@ -39,6 +44,7 @@ public class InputDevice {
final AbsoluteInfo absY;
final AbsoluteInfo absPressure;
final AbsoluteInfo absSize;
+ final TransformInfo tInfo;

long mKeyDownTime = 0;
int mMetaKeysState = 0;
@@ -595,15 +601,29 @@ public class InputDevice {
final AbsoluteInfo absSize = device.absSize;
for (int i=0; i 0) {
+ int i;
+ for (i = 0 ; i < len =" i;" st =" new" t =" new" x1 =" Integer.parseInt(" y1 =" Integer.parseInt(" z1 =" Integer.parseInt(" x2 =" Integer.parseInt(" y2 =" Integer.parseInt(" z2 =" Integer.parseInt(" s =" Integer.parseInt(" tinfo =" t;" debug =" false;" debug_virtual_keys =" false;" debug_pointers =" false;" debug_pointers =" true;" bad_touch_hack =" true;" bad_touch_hack =" false;" excluded_devices_path = "etc/excluded-input-devices.xml" max_processes =" 2;" max_processes =" 10;">

There you have it a calibrated touchscreen working in Android.

I was able to make this work because of lot of work I found online in discussion forums and blogs. Here are the reference to their work:

  • http://groups.google.com/group/android-internals/browse_thread/thread/25a8ccefeb362fd1/8705c88c4b68ab8a?#8705c88c4b68ab8a
  • http://groups.google.com/group/android-porting/browse_thread/thread/fd1bb870ce8d7b2d/45be0fd8eb43d59a?#45be0fd8eb43d59a
  • http://groups.google.com/group/android-porting/browse_thread/thread/211d654dbd0f3f99/2d34279ae278f135?lnk=gst&q=touch+calibration#2d34279ae278f135
  • http://groups.google.com/group/android-porting/browse_thread/thread/fb64af66b1f877fa/8708ab0ea2b9b545?hl=en&lnk=gst&q=touch+screen+top+bar#
  • http://groups.google.com/group/android-porting/browse_thread/thread/9ea3b46fe87d1e3/589c7c6ebd238755?lnk=gst&q=touch+calibration#
  • http://groups.google.com/group/android-porting/browse_thread/thread/9ea3b46fe87d1e3/589c7c6ebd238755?lnk=gst&q=touch+calibration#
  • http://www.opentom.org/Tslib
  • http://androidzaurus.seesaa.net/article/96581331.html

  • Boot loader Porting

    Posted by Vaisakh P S On 6:13 AM 0 comments

    In comparison to Windows CE, in Linux, we have many choices of boot loaders available today. U-Boot [V] is one of most commonly used boot loader in development phase, as it provides with a wide array of features which a developer can make use of. Before starting off with kernel porting these are the features that needs to bring up in U-boot.

    · Debug Consoles – Preferably a serial UART. In u-boot configuration header, the stdin, stdout and stderr need to be specified. In case of our platform, the debug console has been directed to FFUART. Also baud rate of the serial UART connection needs to be configured.

    · Ethernet connection – In initial stages of porting, the kernel image can be transferred over Ethernet instead of flashing on to a ROM. In case of our platform, Ethernet connectivity is provided through the debug card. Enable the use of SMC911X driver in configuration header and set the associated configurations such as Ethernet MAC, Base address, 16-bit or 32-bit Bus mode etc too.

    · Initialization of Memory System – Both boot loader and operating system will be executing in RAM. So RAM needs to initialized to proper timings and U-Boot should be made aware of available RAM though the configuration header.

    · TFTP Server Settings – The IP address of TFTP server along needs to be specified to fetch the kernel image.

    · Kernel Boot arguments – All information of hardware like available RAM, MTD partitions etc are passed on to the kernel as ATAG list. Some of the major arguments that needs to be passed on the kernel are:

    Kernel default console

    Root file system path

    Initrd to use (optional)

    Display

    Init Path

    The purpose of each of these arguments will be explained in subsequent sections.

    Notes

    · While loading OS Image and other File system images over Ethernet or any other medium, pay attention to the load address, make sure that they are not over lapping.

    · It is advisable to make the root file system as Read-only while mounting or in Bootargs to avoid corruption. This will enable bringing up the system with a basic environment.

    Working with Toolchains

    Posted by Vaisakh P S On 6:09 AM 0 comments

    In porting any GNU based software, the first and fore most aspect that needs to be looked into is availability of Tool chain for that platform. I started trying out various pre-built toolchain that was available in Internet and which was provided in Marvell Site. They had various disadvantages

    Toolchain provided by Marvell

    · This toolchain supported EABI what was required by Android but lacked --sysroot option which an utmost necessity for root file system generation utilities like buildroot and other utilities.

    · For the initial few weeks of development, this toolchain was used for porting Kernel and Boot loader, until another toolchain was prepared

    Code Sorcery GNU Toolchain

    · The binaries generated from this toolchain seemed to have different behavior compared to the one generated by the Marvell toolchain. So further experimentation

    So considering these points, I decided to create a custom compiler tool chain. This was made possible by using build scripts like CrossTools and CrossTools-NG. Using CrossTools-NG, we can generate Cross Compiler toolchain which includes the following utilities

    • GCC
    • G++
    • BinUtils
    • C Library (with choices of flavor between ucLibc or Glibc)
    • GDB Host and Target binaries (optional, and is not included in current toolchain).

    The toolchain and the output target binaries has proven to be stable till now. Here are the main options by which the current toolchain has been built:

    CT_ARCH_SUPPORTS_BOTH_ENDIAN

    CT_ARCH_ARCH="iwmmxt" - which is the Xscale core.

    CT_ARCH_FLOAT_SW

    CT_ARCH_arm

    CT_ARCH_USE_MMU

    CT_ARCH_ARM_EABI - Android requires EABI support and this will enhance floating point performance of binaries.

    CT_KERNEL_V_2_6_27_35 – Close to the kernel version used for porting

    CT_BINUTILS_V_2_19_1

    CT_CC_V_4_3_4

    CT_CC_SUPPORT_CXX

    CT_LIBC="glibc" – Other option was ucLibc, but in this case I chose glibc

    CT_LIBC_V_2_9

    CT_GMP_MPFR

    CT_MPFR_V_2_4_1

    CT_TOOLS_WRAPPER_SCRIPT

    Here are some pitfalls and key points that needs to be taken in to account while choosing or making a toolchain.

    • For compiling Glibc, the version of kernel headers needs to be specified. This is a very important factor and it is preferable to use header of the kernel which you are porting to your hardware. While running an application compiled with a specific Glibc version, it checks for the running kernel, if the kernel version is older than version of headers against which Glibc is compiled too, the it will report a FATAL error saying that “FATAL: kernel too old” and program will terminate.

    • Selection of options such as WCHAR support, Locale, Largefile support etc for C Library is at developer's discretion, but bear in mind that if the library doesn't have these feature enabled, they cannot be enabled in buildroot or kernel which uses these libraries and toolchain.

    Android Running on AT91SAM9G45

    Posted by Vaisakh P S On 4:12 AM 0 comments

    Check out this cool video demo about Android running on a AT91SAM9G45 board.

    My Linux Porting Bible

    Posted by Vaisakh P S On 2:35 AM 0 comments

    I found this page to be really useful during porting of U-boot and Linux kernel.


    Hello World

    Posted by Vaisakh P S On 1:00 AM 0 comments

    Hi Everyone,


    I have started this blog to share my experiences on working on Embedded Linux. Hope this would prove helpful for someone

    Regards,
    Vaisakh P S