Ubuntu for Android on XOLO X900

This post is synchronized from (click here for best display effect): https://zohead.com/archives/ubuntu-for-xolo-x900/

Lava XOLO X900 smartphone use Intel Atom Z2460 x86 CPU, so we can try to make some modifications to default Android system, then we can get a tentative Ubuntu for Android system. The important part of this is we can run x86 version Ubuntu, which is much more useful than ARM version Ubuntu (you can do nothing without source code, no proprietary software at all).

Let's see the final Ubuntu for Android effect (on Motorola LapDock 100):

For now, I can run some quite useful program like: Skype, Ubuntu One, sopcast in this Ubuntu system on Android. And the most brilliant thing is we can run Ubuntu and Android system simultaneously, Ubuntu is running on another display screen, doesn't affect Android system at all, we don't need VNC to remote login to Ubuntu.

Click here for introduction about Canonical's Ubuntu for Android:

http://www.ubuntu.com/devices/android

Requirements of Canonical's Ubuntu for Android:

  • Dual-core Android smartphone, at least 512MB RAM;
  • support secondary frame buffer;
  • support USB OTG

While sad point is secondary frame buffer is not enabled on XOLO X900, cause stock kernel only register a /dev/graphics/fb0 frame buffer device. But we the powerful USB OTG, so we can use USB external display adapter to provide secondary frame buffer.

Devices & accessories we need:

  • Motorola LapDock 100 (for display screen, keyboard and mouse input, quite convenient, of course you can use your own display device)
  • DisplayLink USB display adapter
  • USB OTG cable
  • HDMI cable

1. Prepare x86 Ubuntu system:

Cause XOLO X900 only has 16GB ROM space, and consider about speed and expansibility, you'd better use Class 10 microSD card (otherwise your Ubuntu system's performance may not be good), and install Ubuntu in hidden microSD slot of XOLO X900.

You can check this Youtube link to install external microSD card in XOLO X900:

http://www.youtube.com/watch?v=6-FkK7Htohs

Now we need a proper Ubuntu system, if you have enough time, you can use VMware to install a full Ubuntu system to your SD card. While I'm lazy, I choose to download existing VMware vmdk image and copy contents to SD card.

I use this Lubuntu 12.04 system, cause it use LXDE desktop, which is quite lightweight and fast compared to default Unity desktop, and you can also download default Ubuntu 12.04 system with Unity desktop from this website:

http://www.trendsigma.net/vmware/lubuntu1204.html

You may need another Linux virutal machine to copy files from this Lubuntu image to your SD card (It's strongly recommended that you should partition your SD card, I create a ext4 partition for Ubuntu here).

2. Prepare driver for DisplayLink USB adapter:

XOLO X900 stock kernel doesn't provide full frame buffer support (lack of defio support and so on), we can't compile the udlfb driver of DisplayLink USB adapter in stock Linux 3.0.8 kernel source.

I've found this old udlfb 0.4 version driver that can be compiled under XOLO X900 stock kernel config, and I also made some modifications to make it actually work. (Default code can't display any thing on screen at all):

http://git.plugable.com/gitphp/index.php?p=udlfb

This is my modified udlfb 0.4 version driver source:

http://miseal.googlecode.com/files/udlfb-v0.4.tar.bz2

Changes from the default udlfb 0.4 code:

  • Fix udlfb can't be compiled in Linux 3.0.8;
  • Fix kzalloc memory allocation bug, use vmalloc instead;
  • Release allocated memory when unload driver;
  • Get display device's proper resolution from EDID, use these resolution by default;
  • If EDID can't any valid resolution, use 1280x1024 by default;
  • Add module parameter, you can specify display resolution when load module

Please check this post by me about how to compiled custom kernel:

https://zohead.com/archives/xolo-x900-kernel/

If you want to use already compiled modules, please download from this link:

http://miseal.googlecode.com/files/x900-kernel-config-modules.7z

The compiled udlfb.ko module is in modules directory, you can copy modules directory to /system/lib directory (root permission is needed).

3. Test udlfb driver module:

First connect your DisplayLink USB display adapter to self-powered external USB hub (Motorola Lapdock is just a self-powered USB HUB ^_^), then connect USB display adapter to your external display device, make sure your phone is rooted, run this command in shell after run su

insmod /system/lib/modules/udlfb.ko

If everything is OK, udlfb driver will automatically detect your display device's resolution, and a green screen should be showed on your screen.

Then run this command to check whether frame buffer device is OK (you should get fb1 device node information output):

ls -l /dev/graphics/fb1

If your display device doesn't support EDID or default 1280x1024 resolution is not supported, you can specify initial resolution at loading module, like this:

insmod /system/lib/modules/udlfb.ko init_xres=1024 init_yres=768

Previous command specify initial resolution to 1024x768.

4. Disable Android support for USB input device:

As XOLO X900 default support USB OTG, when you connect USB keyboard or mouse through OTG to your phone, you can use them to operate on your Android system, and any input event (keyboard pressing or mouse movement) will make Android unlock from sleep, this is quite useless for our Ubuntu for Android, and also it will generate duplicate input event to Android sysem. So we need to disable Android support for USB input device.

First connect your USB keyboard and mouse to USB HUB, and you need to find which is your USB input device, run this command in shell after su:

ls /dev/input/event*

Your will see several input event device, use this command to check whether it's your USB keyboard or mouse device one by one (you need to replace X to number you see, and press key on your USB keyboard or move your USB mouse, if it's the right device, you will see some output):

cat /dev/input/eventX

Let's assume our USB keyboard and mouse device are: /dev/input/event10 and /dev/input/event11.

Then run dmesg command to get device name of your USB input device, you will get some output like this:

usb 1-1: new high speed USB device number 2 using penwell_otg
hub 1-1:1.0: USB hub found
hub 1-1:1.0: 7 ports detected
usb 1-1.1: new full speed USB device number 3 using penwell_otg
input: Motorola Mobility Motorola HD Dock as /devices/pci0000:00/0000:00:02.3/usb1/1-1/1-1.1/1-1.1:1.0/input/input11
generic-usb 0003:22B8:0938.0003: input,hidraw0: USB HID v1.01 Keyboard [Motorola Mobility Motorola HD Dock] on usb-0000:00:02.3-1.1/input0
usb 1-1.3: new low speed USB device number 4 using penwell_otg
input: BTC USB Cordless Mouse as /devices/pci0000:00/0000:00:02.3/usb1/1-1/1-1.3/1-1.3:1.0/input/input12
generic-usb 0003:1241:0003.0004: input,hidraw1: USB HID v1.10 Keyboard [BTC USB Cordless Mouse] on usb-0000:00:02.3-1.3/input0
input: BTC USB Cordless Mouse as /devices/pci0000:00/0000:00:02.3/usb1/1-1/1-1.3/1-1.3:1.1/input/input13
generic-usb 0003:1241:0003.0005: input,hidraw2: USB HID v1.10 Mouse [BTC USB Cordless Mouse] on usb-0000:00:02.3-1.3/input1
usb 1-1.6: new high speed USB device number 5 using penwell_otg

Previous Motorola Mobility Motorola HD Dock and BTC USB Cordless Mouse is your USB keyboard and mouse device name, please note these names.

Edit /system/etc/excluded-input-devices.xml configuration file, add previous found USB input device name to this file, and reboot phone, then USB input event will not affect your Android system or unlock Android from sleep.

For example, this is my config content:

<?xml version="1.0" encoding="utf-8"?>
<devices>
<device name="Unipoint HID"/>
<device name="RMI4 Unipoint"/>
<device name="Motorola Mobility Motorola HD Dock"/>
<device name="BTC USB Cordless Mouse"/>
</devices>

5. Switch from Android to Ubuntu system:

Run su rooted shell, and create a directory as mount point (here is /system/sd) for Ubuntu partition:

mount -o remount,rw /dev/block/mmcblk0p2 /system
busybox mkdir -m 777 /system/sd
mount -o remount,ro /dev/block/mmcblk0p2 /system

Then you can use my startubuntu script to switch from Android to Ubuntu (I mount the first ext4 partition on microSD card here, please modify this script as you like):

http://pastebin.com/raw.php?i=9r21dR7L

I mount /mnt/sdcard directory in Android to /sdcard directory in Ubuntu, and mount /system directory in Android to /android/system directory in Ubuntu, so we can easily access data in Android from Ubuntu system.

6. Prepare X environment in Ubuntu:

Assume you have already switched to Ubuntu, first you can install DisplayLink X display driver:

apt-get install xserver-xorg-video-displaylink

then install X input module:

apt-get install xserver-xorg-input-evdev

after install completes, you need to modify /etc/X11/xorg.conf X11 configuration file (Note: Ubuntu 12.04 doesn't contain this file, you need to create your own X11 configuration file in /usr/share/X11/xorg.conf.d directory, mine is: 52-displaylink.conf), config content is in this link:

http://pastebin.com/raw.php?i=WjcfFWc2

And don't forget to change the input devices and display resolution as your need.

7. Run X - Finally Ubuntu for Android:

Generate a init configuration file for X, vi /root/.xinitrc

#!/bin/sh
xrandr -o 0
startlubuntu

xrandr command in the second line is a special fix for DisplayLink udlfb driver, without this, menu items will not be displayed correctly in X desktop environment. And you can replace startlubuntu command to any X init command as you like (like: xinit lxsession).

Then you can execute startx command to start X desktop.

If you encounter VT number error and fail to start X, you can add VT parameter to startx command:

startx -- :0 vt1

If this work, it means X use invalid VT number, and you may need to modify /etc/X11/xinit/xserverrc configuration file to force VT number for X:

#!/bin/sh
exec /usr/bin/X -nolisten tcp vt1 "$@"

8. Conclusion:

There are some shortcoming you should know about this Ubuntu for Android solution:

  • We need to use external USB display adapter, this is quite inconvenient, and hotplug USB display adapter will crash X server, the best solution should be patching kernel to support HDMI frame buffer;
  • Audio doesn't work yet, you can use USB sound card or send sound to phone directly (very ugly -_-#);
  • Phone can't be charged when connected to external self-powered USB HUB, I think kernel patch is also needed.

This article is based on my experience in the use of Ubuntu for Android, it's not written for common use, please feel free to point out any errors in this ^_^