Skip to content

Adding touch support in Yocto

07-Feb-13

The core-image-sato default image in Yocto has touch support, but chances are it takes some tweaking to make it work. In my case I am using Digi’s ConnectCore for MX51 JumpStart Kit with a custom Yocto image, based in core-image-sato, and a resistive touch. The touch is driven by the MXC_TS driver from the Freescale BSP for the i.MX5X.

Testing the kernel touch support

Some basics checks to make sure the touch is functional:

dmesg should show:
user@computer:$
input: mxc_ts as /devices/virtual/input/input0
mxc input touchscreen loaded

And the information in the sys filesystem should be:
user@computer:$
cat /sys/devices/virtual/input/input0/uevent
PRODUCT=0/0/0/0
NAME="mxc_ts"
EV==b
KEY==400 0 0 0 0 0 0 0 0 0 0
ABS==1000003
MODALIAS=input:b0000v0000p0000e0000-e0,1,3,k14A,ra0,1,18,mlsfw

user@computer:$
cat /sys/devices/virtual/input/input0/event0/uevent
MAJOR=13
MINOR=64
DEVNAME=input/event0

Then you can check whether the driver works by doing.
user@computer:$
cat /dev/input/event0 | hexdump
0000000 002e 0000 f889 0008 0003 0000 06cb 0000
0000010 002e 0000 f89f 0008 0003 0001 03c2 0000
0000020 002e 0000 f8a5 0008 0003 0018 0001 0000
0000030 002e 0000 f8ab 0008 0000 0000 0000 0000
0000040 002e 0000 f27b 0009 0003 0000 001f 0000

Which should update continuously when you touch the screen. If that does not work you either have a configuration or kernel driver issue.

User space touch support

Usually embedded distributions have been using tslib for touch support, so I like starting with tslib and its test applications ts_calibrate and ts_test over the framebuffer.

If you do:
user@computer:$
export TSLIB_TSDEVICE="/dev/input/event0"
export TSLIB_CONFFILE="/etc/ts.conf"
/usr/bin/ts_calibrate

You should see the arrows and be able to calibrate a resistive touch.And /usr/bin/ts_test should allow you to see the touch working.
Now we get into the Yocto SATO image. The default Xorg driver used is evdev, which interfaces to the kernel’s event interfaces, evdev, which needs udev to be functional. For more details read this for an overview of the Linux input system.
The default Xorg configuration is:
user@computer:$
cat /etc/X11/xorg.conf
Section "Device"
Identifier "i.MX Accelerated Framebuffer Device"
Driver "imx"
Option "fbdev" "/dev/fb0"
# This option only recognized when "mxc_epdc_fb" frame buffer driver in
# use. Values are "RGB565" (default, 16-bit RGB), "Y8" (8-bit gray),
# and "Y8INV" (8-bit gray inverted).
Option "FormatEPDC" "Y8INV"
EndSection

Section "ServerFlags"
Option "BlankTime" "0"
Option "StandbyTime" "0"
Option "SuspendTime" "0"
Option "OffTime" "0"
EndSection

Which omits the InputDevice sections. Looking around (with the help of /var/log/Xorg.0.log) we find them in /usr/share/X11/xorg.conf.d/:
user@computer:$
cat 10-evdev.conf
#
# Catch-all evdev loader for udev-based systems
# We don't simply match on any device since that also adds accelerometers
# and other devices that we don't really want to use. The list below
# matches everything but joysticks.

Section "InputClass"
Identifier "evdev pointer catchall"
MatchIsPointer "on"
MatchDevicePath "/dev/input/event*"
Driver "evdev"
EndSection

Section "InputClass"
Identifier "evdev keyboard catchall"
MatchIsKeyboard "on"
MatchDevicePath "/dev/input/event*"
Driver "evdev"
EndSection

Section "InputClass"
Identifier "evdev touchpad catchall"
MatchIsTouchpad "on"
MatchDevicePath "/dev/input/event*"
Driver "evdev"
EndSection

Section "InputClass"
Identifier "evdev tablet catchall"
MatchIsTablet "on"
MatchDevicePath "/dev/input/event*"
Driver "evdev"
EndSection

Section "InputClass"
Identifier "evdev touchscreen catchall"
MatchIsTouchscreen "on"
MatchDevicePath "/dev/input/event*"
Driver "evdev"
EndSection

As we see all the input devices are driven by evdev.
We can get some more information using xinput:
user@computer:$
sh-4.2# xinput list
Virtual core pointer id=2 [master pointer (3)]
Virtual core XTEST pointer id=4 [slave pointer (2)]
Dell Dell USB Optical Mouse id=7 [slave pointer (2)]
mxc_ts id=8 [slave pointer (2)]
Virtual core keyboard id=3 [master keyboard (2)]
Virtual core XTEST keyboard id=5 [slave keyboard (3)]
DELL Dell QuietKey Keyboard id=6 [slave keyboard (3)]

user@computer:$
sh-4.2# xinput list-props mxc_ts
Device 'mxc_ts':
Device Enabled (112): 1
Coordinate Transformation Matrix (113): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000
Device Accel Profile (233): 0
Device Accel Constant Deceleration (234): 1.000000
Device Accel Adaptive Deceleration (235): 1.000000
Device Accel Velocity Scaling (236): 10.000000
Device Product ID (230): 0, 0
Device Node (231): "/dev/input/event0"
Evdev Axis Inversion (237): 0, 0
Evdev Axis Calibration (238): 985, 42, 935, 58
Evdev Axes Swap (239): 1
Axis Labels (240): "Abs X" (254), "Abs Y" (255), "Abs Pressure" (256)
Button Labels (241): "Button Unknown" (232), "Button Unknown" (232), "Button Unknown" (232), "Button Wheel Up" (118), "Button Wheel Down" (119)
Evdev Middle Button Emulation (242): 0
Evdev Middle Button Timeout (243): 50
Evdev Third Button Emulation (244): 0
Evdev Third Button Emulation Timeout (245): 1000
Evdev Third Button Emulation Button (246): 3
Evdev Third Button Emulation Threshold (247): 20
Evdev Wheel Emulation (248): 0
Evdev Wheel Emulation Axes (249): 0, 0, 4, 5
Evdev Wheel Emulation Inertia (250): 10
Evdev Wheel Emulation Timeout (251): 200
Evdev Wheel Emulation Button (252): 4
Evdev Drag Lock Buttons (253): 0

Theoretically we only have to launch xinput-calibrator and the touch will calibrate itself.
In practise, this only works if the touch has already been calibrated beforehand. With the default values it gets from xinput, the calibration does not work.  I haven’t looked into the code, but the project has a list of unanswered open bugs some of which already report this.
What can we do? Manual calibration for starters, and then xinput-calibrator for accuracy.

Manual touch calibration

For manual calibration you need to use the evtest application. If using Yocto just do:

user@computer:$
bitbake evtest

And then install the package it builds. In my case the package lives in tmp/work/armv7a-vfp-neon-del-linux-gnueabi/evtest-1.25-r0/deploy-ipks.
user@computer:$
evtest /dev/input/event0

Or whichever eventN your touch is in, and touch the four corners of your screen writting down the X,Y values. Evtest will show the RAW touch values. In my case the mxc_ts driver is working through a 10bits ADC, so the resolution is 0 to 1023.
user@computer:$
evtest /dev/input/event0
Input driver version is 1.0.0
Input device ID: bus 0x0 vendor 0x0 product 0x0 version 0x0
Input device name: "mxc_ts"
Supported events:
Event type 0 (Sync)
Event type 1 (Key)
Event code 330 (Touch)
Event type 3 (Absolute)
Event code 0 (X)
Value 340
Min 0
Max 1023
Event code 1 (Y)
Value 430
Min 0
Max 1023
Event code 24 (Pressure)
Value 0
Min 0
Max 1023
Testing ... (interrupt to exit)
Event: time 3872.440377, type 3 (Absolute), code 0 (X), value 914
Event: time 3872.440383, type 3 (Absolute), code 1 (Y), value 966
Event: time 3872.440386, type 3 (Absolute), code 24 (Pressure), value 46
Event: time 3872.440388, type 1 (Key), code 330 (Touch), value 1
Event: time 3872.440391, -------------- Report Sync ------------
Event: time 3872.470939, type 3 (Absolute), code 0 (X), value 909
Event: time 3872.470945, type 3 (Absolute), code 1 (Y), value 970
Event: time 3872.470950, -------------- Report Sync ------------
Event: time 3872.501124, type 3 (Absolute), code 24 (Pressure), value 0
Event: time 3872.501130, type 1 (Key), code 330 (Touch), value 0
Event: time 3872.501132, -------------- Report Sync ------------

The touch screen size is 800×480, and the translation between the raw resolution and the screen resolution is what calibration is about.
Once you have them all do:
user@computer:$
xinput set-prop "mxc_ts" "Evdev Axis Calibration" xmin xmax ymin ymax

If you need to swap the XY axis, you can also do it with:
user@computer:$
xinput set-prop "mxc_ts" "Evdev Axes Swap" 1

The touch should work now. And xinput-calibrator should too. To make the calibration permanenent have a read at the different options here.
My recommendations would be either altering the Xorg configuration to:
user@computer:$
Section "InputClass"
Identifier "evdev touchscreen catchall"
MatchIsTouchscreen "on"
MatchDevicePath "/dev/input/event*"
Driver "evdev"
Option "Calibration" "xmin xmax ymix ymax"
Option "SwapAxes" "1"
EndSection

Or use the pointercal.xinput file as described in the link above.

Encrypting folders with ecryptfs

28-Jan-13

Ecryptfs can encrypt partitions or directores without its own partition. All the information needed to decrypt is contained on the files themselves, so it’s ideal for backup and restoration on any other system.

To create an encrypted folder:

sudo apt-get install ecryptfs-utils
mount -t ecryptfs /path/folder /path/folder

It will ask a few questions, starting with a passphrase. Enter the passphrase and leave all as defaults (aes, 16 bytes, no plaintext passthrough, no filename encryption, append signature to /root/.ecryptfs/sig-cache.txt).

mount will show (with your own ecryptfs_sig):

/path/folder on /path/folder type ecryptfs 
    (rw,ecryptfs_sig=bd28c38da9fc938b,ecryptfs_cipher=aes,ecryptfs_key_bytes=16,ecryptfs_unlink_sigs)

You follow the same steps to mount an existing encrypted folder. If you have never mounted that filesystem on the computer you are using you will see:

WARNING: Based on the contents of [/root/.ecryptfs/sig-cache.txt],
it looks like you have never mounted with this key
before. This could mean that you have typed your
passphrase wrong.
Would you like to proceed with the mount (yes/no)?

Just type yes, it’s a safe answer.

Git stash tricks

17-Dec-12

Stashing only specific files

git stash --patch
  • d Skip file
  • a Stash file
  • q Quit

Stash stuff that has not been added

git add the things you want to keep, then run:

git stash --keep-index

Splitting an old commit into more than one changeset

git rebase -i
    Mark some changes as edit.
git reset HEAD^
git add 
git stash --keep-index
    Fix things up as necessary. Don't forget to git add any changes.
git commit
git stash pop
Repeat, from #2, as necessary.
git rebase --continue

Checking out a single file from the stash

git checkout stash@{0} -- path/to/file

Saving a stashed file with a new name

git show stash@{0}:path/to/file  > path/to/file

Installing Sun/Oracle Java in Ubuntu

05-Dec-12
This is a nice script that will create the .deb packages for you to install locally.
user@computer:$ wget https://raw.github.com/thenameisnigel/oab-java6/master/oab-java.sh -O oab-java.sh
chmod u+x oab-java.sh
sudo ./oab-java.sh

Note: The original wrapper script here seems unmaintained, so I am using a fixed fork.

Git branch on shell prompt

30-Nov-12

I have seen instructions for this scattered around, so here is the complete version:

user@computer:$ git clone git://git.kernel.org/pub/scm/git/git.git

user@computer:$ cp git/contrib/completion/git-completion.bash ~/.git-completion.sh

user@computer:$ chmod u+x ~/.git-completion.sh

Edit ~/.bashrc:

# Source a git completion script
if [ -f $HOME/.git-completion.sh ]; then
       . $HOME/.git-completion.sh
else
  echo "Could not find git completion script"
fi
 
# Display the current git branch in the command prompt
export PS1='\u@\h \w$(__git_ps1 " (\[\e[1;32m\]%s\[\e[0m\])")\$ '

The result is:

alex@katana ~/meta-openembedded (master)$

Introduction to Yocto

06-Sep-12

The following presentation contains information already present in Yocto’s documentation but ordered in an easier to make sense of way.

The Linux kernel VM split and Android user space

05-Jun-12

The VM split defines the virtual memory areas for user space (highmem) and kernel space (lowmem). The kernel has direct access to lowmem, and an area of lowmem is reserved to map the highmem area so that the kernel can also access it if it needs to.

The VM split deals with virtual memory mapping, nothing to do with physical memory or extended addressing schemes like Intel’s PAE for 32bits machines. 64bits machine do not use the VM split so user space can get very large.

An Intel 32bits machine with PAE can reach memory above 4GB, but the maximum split is still 3:1, so the maximum for user space is still 3G. The whole memory is reachable, but not all mappable into address space. And unmappable portions are not usable.

VMSPLIT3G (1GB kernel/3Gb user space)

# 0xC0000000 - 0xFFFFFFFF Kernel
# 0xB0100000 - 0xBFFFFFFF Thread 0 Stack
# 0xB0000000 - 0xB00FFFFF Linker
# 0xA0000000 - 0xBFFFFFFF Prelinked System Libraries
# 0x90000000 - 0x9FFFFFFF Prelinked App Libraries
# 0x80000000 - 0x8FFFFFFF Non-prelinked Libraries
# 0x40000000 - 0x7FFFFFFF mmap'd stuff
# 0x10000000 - 0x3FFFFFFF Thread Stacks
# 0x00000000 - 0x0FFFFFFF .text / .data / heap

VMSPLI2G (2GB kernel/2GB user space)

# 0x80000000 - 0xFFFFFFFF Kernel
# 0x70100000 - 0x7FFFFFFF Thread 0 Stack
# 0x70000000 - 0x700FFFFF Linker
# 0x60000000 - 0x6FFFFFFF Prelinked System Libraries
# 0x50000000 - 0x5FFFFFFF Prelinked App Libraries
# 0x40000000 - 0x4FFFFFFF Non-prelinked Libraries
# 0x2AAAAAAA - 0x3FFFFFFF mmap'd stuff
# 0x10000000 - 0x2AAAAAA9 Thread Stacks
# 0x00000000 - 0x0FFFFFFF .text / .data / heap

The Android user space (I am looking at 2.3.7) uses a KERNEL_IS_2G define to set the prelinked map and library space:

In bionic/linker/linker.h:

#ifdef KERNEL_IS_2G
#define LIBBASE 0x40000000
#define LIBLAST 0x50000000
#else
#define LIBBASE 0x80000000
#define LIBLAST 0x90000000
#endif

And in build/tools/apriori/prelinkmap.c:

#ifdef KERNEL_IS_2G
#define PRELINK_MIN 0x50000000
#define PRELINK_MAX 0x7FFFFFFF
#else
#define PRELINK_MIN 0x90000000
#define PRELINK_MAX 0xAFFFFFFF
#endif

So the user space needs to be recompiled for the specific VM split the kernel is set to.

Android GitWeb

23-Feb-12

Since the kernel.org servers were hacked a browsable repository can be found here.

Android kernel sources download and compilation

23-Feb-12

Compile Android’s kernel tree

user@computer:$ git clone https://android.googlesource.com/kernel/common.git linux-android
cd linux-android
git branch -r

origin/HEAD -> origin/master
origin/android-2.6.39
origin/android-3.0
origin/android-3.3
origin/master

git checkout origin/android-2.6.39
make ARCH=arm CROSS_COMPILE=${SDK_ROOT}}/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi- mx51_defconfig
make -j4 ARCH=arm CROSS_COMPILE=${SDK_ROOT}}/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-

This generates a file named arch/arm/boot/zImage

Compile Android’s emulator kernel

user@computer:$ git clone https://android.googlesource.com/kernel/goldfish.git
git checkout origin/android-goldfish-2.6.29
make ARCH=arm CROSS_COMPILE=${SDK_ROOT}}/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi- goldfish_defconfig # configure the armv5 kernel
make ARCH=arm CROSS_COMPILE=${SDK_ROOT}}/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi- goldfish_armv7_defconfig # configure the armv7 kernel
make -j4 ARCH=arm CROSS_COMPILE=${SDK_ROOT}}/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-

This generates a file named arch/arm/boot/zImage

Both the standard and emulator kernels are provided precompiled in the SDK at ${SDK_ROOT}/prebuilt/android-arm/kernel.

You can now run the emulator as:

user@computer:$ make sdk -j4
${SDK_ROOT}/out/host/linux-x86/bin/emulator -kernel ${SDK_ROOT}/prebuilt/android-arm/kernel/kernel-qemu-armv7 -show-kernel -verbose

Note that as a convenience, if the name of the kernel image ends with -armv7, then the cortex-a8 emulation will be turned on automatically. Otherwise you would have to pass the flags manually (-qemu -cpu cortex-a8).

Reportedly the qemu emulator included in the Android SDK doesn’t support ARMv7 emulation properly.

Android’s partition images

23-Feb-12

Ramdisk

A ramdisk.img (initrd) 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.

ramdisk.img is included ($SDK_ROOT/tools/lib/images/ramdisk.img) or compiled ($SDK_ROOT/out/target/product/$PRODUT_NAME/ramdisk.img) by the google android sdk. It’s in a gzipped cpio file.

Modifying Android’s ramdisk image

To modify it, first copy it to your Linux machine and extract it as follows:

user@computer:$ mv ramdisk.img ramdisk.cpio.gz
gzip -d ramdisk.cpio.gz
cpio -i -F ramdisk.cpio

Make any changes you want to the extracted ramdisk.cpio, and remove the unneeded files. Recreate the ramdisk.cpio with command:

user@computer:$ cpio -i -t -F ../ramdisk.cpio | cpio -o -H newc -O ../ramdisk_new.cpio

System and data images

The system.img is a partition image that will be mounted as / and thus contains all system binaries.
The userdata.img is a partition image that can be mounted as /data and thus contains all application-specific and user-specific data.

On the real device they have to be mounted by the init.rc script which runs from the ramdisk. They can be of different formats, usually YAFFS2, EXT4 or UBI-FS.

They are generated by the build system and can be used to flash to a real device. The emulator uses them differently (see below)

Android emulator images

  • system.img is copied into a temporary file, which is used by the emulator session. So any change you make to / as root in the emulator are lost when the program exits
  • userdata.img is only used when you use -wipe-data. Instead, it uses ~/.android/userdata-qemu.img (on Linux) as the persistent /data partition image. Using -wipe-data simply copies the content of userdata.img into userdata-qemu.img
  • sdcard.img, if present or specified with -sdcard , corresponds to /sdcard
  • cache.img if specified in the emulator with -cache corresponds to /cache. if none is specified, an empty temporary file is created at emulator startup and /cache will be mounted to it. this temp file is automatically cleaned up at exit.

The emulator will not modify system.img and userdata.img since they were generated as device images.

Extracting Android’s YAFFS2 images

A YAFFS2 file is identied as a “VMS Alpha executable” by Linux.

user@computer:$ file ${SDK_ROOT}}/out/target/product/imx51_ccwmx51js/system.img
./out/target/product/imx51_ccwmx51js/system.img: VMS Alpha executable

Download unyaffs from the unyaffs Google Project Hosting.

If the executable does not work on your system you can download the source and recompile it.

user@computer:$ gcc -o unyaffs unyaffs.c
sudo chmod +x /complete/directory/path/to/unyaffs

Copy the YAFF2 img files to the same folder and extract them:

user@computer:$ ./unyaffs system.img
./unyaffs data.img
./unyaffs cache.img

Extracting JFFS2 images

Just for completion, here is how to extract a JFFS2 image.

user@computer:$ modprobe mtdblock
modprobe jffs2
modprobe mtdram total_size=65536 erase_size=256
mknod /tmp/mtdblock0 b 31 0
dd if=/pathtoimage/rootfs.jffs2 of=/tmp/mtdblock0
mount -t jffs2 /tmp/mtdblock0 /mnt