Sunday, February 12, 2012

Android on your EEEPC

Hello everyone,

So, this article is about running Android on your x86 computer, here we'll use the eee-pc since that is supported in a very nice way by the people behind the android-x86 project.

What you will get:
  • Ice Cream Sandwich
  • A Live-USB stick that you can boot android from without touching your installed software/os at all. Or you can choose to install it to hard-drive, enabling you to keep changes you make over reboots.
  • Camera is working
  • WLAN is working
  • Google Apps are installed (Market, Talk, GMail etc)

What's not working
  • Youtube
  • Face unlock
  • Many android-apps that expect ARM architecture

So, you could just download the iso from http://www.android-x86.org . But then you would get an image where you can't use the browser and you can't read e-mail. Also, you would miss out on the fun on rolling your own bleeding edge android rom :)

First, this article is standing on the shoulders of giants, most of the information has been taken and tweaked from these web-pages. But as usual, the devil is in the details.

Links

Get the install dependencies (for 64bit ubuntu 11.10)
Get the packages from the Ubuntu repository
sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev libc6-dev lib32ncurses5-dev ia32-libs x11proto-core-dev libx11-dev lib32readline-gplv2-dev lib32z-dev libgl1-mesa-dev g++-multilib mingw32 tofrodos python-markdown libxml2-utils xsltproc openjdk-6-jdk

sudo apt-get install libx11-dev:i386
Get Repo
mkdir ~/bin
export PATH=~/bin:$PATH
curl https://dl-ssl.google.com/dl/googlesource/git-repo/repo > ~/bin/repo
chmod a+x ~/bin/repo

Get the android-x86 source code
A warning, on the android-x86 page, they tell you to use the sourceforge mirror, I had problems with that one. I didn't get all dependencies downloaded. I got a repo-warning about libcamera and I got lots of build-errors about LOCAL_SDK_VERSION being set to bad values. This turned out to be because I had no prebuilt directory. After I re-downloaded everything and used the android-x86 git-repository, I got everything and compilation was smooth as butter :) (Well, almost, it didn't like OpenJDK, but that was a simple fix).

mkdir -p ~/devel/android-x86
cd ~/devel/android-x86
repo init -u http://git.android-x86.org/manifest -b $branch
# This will download about 11GB worth of data!
repo sync
Then, enable building with OpenJDK
I did this by going in to build/core/ and creating a new git-branch. The reason for this is that it makes it easier when there is an update available from upstream, you can just do repo sync and then rebase your branch to be on top of it.
cd build/core
git checkout -b fix_jdk
And then apply this patch which is inlined here:
diff --git a/core/main.mk b/core/main.mk
index 569d4dc..2912c70 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -114,9 +114,9 @@ endif
# Check for the correct version of java
java_version := $(shell java -version 2>&1 | head -n 1 | grep '^java .*[ "]1\.6[\. "$$]')
-ifneq ($(shell java -version 2>&1 | grep -i openjdk),)
-java_version :=
-endif
+#ifneq ($(shell java -version 2>&1 | grep -i openjdk),)
+#java_version :=
+#endif
ifeq ($(strip $(java_version)),)
$(info ************************************************************)
$(info You are attempting to build with the incorrect version)
You can apply it by:

cd ~/devel/android-x86/build
# this should of course be the path to where you have stored the patch
patch -p0 < openjdk.patch

Then source build environment and start build
This will take a while, I think it took about 1 hour for me (quad-core amd 3ghz, 8gb ram and ssd disk).
cd ~/devel/android-x86
source build/envsetup.sh
# you could probably also build a user-build with: lunch eeepc-user
lunch eeepc-eng
# m is shorthand for make, the macro is in envsetup.sh
# This also makes sure that you can be in any directory and still get a proper build
m -j4 iso_img

While you wait, download gapps (at the time of writing gapps-ics-20120207-signed.zip)

Unpack to ~/devel/android-gapps
mkdir -p ~/devel/android-gapps
mv ~/Downloads/gapps* ~/devel/android-gapps
cd ~/devel/android-gapps
unzip gapps*
Create directory for patching generated iso-image

mkdir ~/devel/android-hacking
Wait for build to complete. Now comes the tricky part. First, the build will create an iso-image that doesn't have google apps. Also, this image does not have room in it to add the google apps package. So we will unpack the iso-image, resize the system filesystem, add gapps package and then sew everything back up afterwards.
cp ~/devel/android-x86/out/target/product/eeepc/eeepc.iso ~/devel/android-hacking
cd ~/devel/android-hacking

mkdir android-image
mkdir tmp

# extract image to android-image directory
bsdtar -C android-image -xf eeepc.iso
cd android-image
# if your system image is squashed (I didn't do this. It can be configured, then run)
unsquashfs system.sfs
# resize system.img so we can fit gapps, could probably be enough with 100 mb instead of 256.

dd if=/dev/zero bs=1M count=256 >> system.img
resize2fs system.img
$ cd ..
# if squashed
$ sudo mount -o loop android-image/squashfs-root/system.img tmp
# else
$ sudo mount -o loop android-image/system.img tmp
Now we have extracted the iso, resized the system partition and loopback mounted it to the tmp directory (meaning, we can use it as a normal file-system).

Install gapps into android system.
Now we will install the gapps. The gapps package I used is for arm-devices. Therefore we can only use the apps that only have a java/dalvik component. The ones that use ndk and arm-specific libraries can't be used.

sudo cp ../android-gapps/system/app/* tmp/app
sudo cp ../android-gapps/system/etc/permissions/* tmp/etc/permissions/
sudo cp ../android-gapps/system/framework/* tmp/framework/
There, now we have everything where we want it. Time to wrap it up.
Begin by unmounting the tmp directory so we get the system.img back as it should be
sudo umount tmp
# if squashed
mksquashfs android-image/squashfs-root/system.img system.sfs

Create iso-image
genisoimage -vJURT -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -input-charset utf-8 -V "Android-x86 LiveCD" -o eeepc-gapps.iso android-image/

Make it bootable from USB
isohybrid eeepc-gapps.iso

Write it to USB
Now everything is done. you have a file eeepc-gapps.iso that you can burn to a cd or install on a usb-stick. I very much prefer USB. This is how you get it to a usb-stick. First you need to be sure where your USB-stick is. If you get this wrong, you will Kill one of your harddrives. You don't want that. If you are unfamiliar with using the terminal, please use unetbootin or some other tool to write the image to a usb-stick.
sudo dd if=eeepc-gapps.iso of=/dev/sdc


There, you did it!
Now you can put your USB stick in an eee-pc and boot it. I had to go into the BIOS and change the boot-order since my USB-stick showed up as a hard-disk.

But after that, whenever you boot with this usb-stick plugged in, you will get android Ice Cream Sandwich instead of your other operating systems! :)

Some things are left to do though
  • This won't store settings over rebooots.
  • It won't handle suspends very well
  • Since I don't have a x86 gapps package, not all features work (Face unlock, youtube)
Maybe I'll write another article when I've fixed that :)

Cheers,
Daniel

Thursday, November 17, 2011

Close, but not good enough. Eclipse in Ubuntu

So, I recently reinstalled Ubuntu and therefore I need to set up my Android development environment again.

I saw that Ubuntu ships Eclipse 3.7 now. Woot! Reasonably new version! Very nice.

Except, Android Development Tools can't be installed since Eclipse Marketplace isn't included by default. What's the favorite solution? Download a new version of Eclipse that has it.

No. I don't want to do that.

So, If you add the Indigo repository to eclipse.
Install new Software -> Add new repository


Then you go to
Install new Software -> Switch to the Indigo Repository -> General Purpose Tools -> Marketplace Client

Install that one.

Now we can go on to installing the Android tools by adding a new software repository:

https://dl-ssl.google.com/android/eclipse/
Now, proceed as normal with installing all developer tools from there.

By the way, why can't eclipse have their repository over https?

Cheers,
Daniel

Backing up your Ubuntu installation

I recently was in the process of migrating from on disk to the next and wanted to make a complete copy of the old one. I use Ubuntu and I had tried out using EcryptFS for my home-folder instead of having whole-disk encryption as I usually have.

Backing things up is easy with dd, a tool that reads whatever you point it to and writes it wherever you point it to. For example:

# dd if=/dev/sda of=/other_disk/backup_of_sda.img bs=1M
This will copy your entire harddrive into a file that you can then loopback mount to create a virtual harddrive. You can also copy just a specific partition by specifying /dev/sda1 and then you can skip the first step of opening it.

Remember, do not do this while you use your disk, so if it's your main drive, boot from a live-cd and do this.

So, now you have an image, how do you access it?

You can open it with parted and list partitions that you can mount (not necessary if you only copied partitions previously).

# parted /other_disk/backup_of_sda.img
GNU Parted 2.3
Using /other_disk/backup_of_sda.img
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) unit
Unit? [compact]? B
(parted) print
Model: (file)
Disk /other_disk/backup_of_sda.img: 80026361856B
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number Start End Size Type File system Flags
1 32256B 477066239B 477033984B primary ext3 boot
2 477066240B 75886433279B 75409367040B primary ext4
3 75886433280B 80023749119B 4137315840B primary linux-swap(v1)
This is the output form my 80GB disk, it has a boot, a primary and a swap at the respective offsets.

Now, I want to mount the primary file system, i do that like this:

# mount -o loop,rw,offset=477066240 /other_disk/backup_of_sda.img /mnt/sda_backup
Now we can access files from it. Except the files in the home directory are encrypted with EcryptFS.

The way I went about this was to create a complete chroot in the /mnt/sda_backup and then use its own EcryptFS tools.

mount --bind /proc/ /mnt/sda_backup/proc
mount --bind /dev/ /mnt/sda_backup/dev
mount --bind /sys/ /mnt/sda_backup/sys
chroot /mnt/sda_backup
Now we're inside our old system and can manipulate it any way we want.
EcryptFS is a bit uncomfortable to work with, but I found this script that makes it a bit easier:

ROOT=/home/.ecryptfs/$USER
TARGET=/mnt/$USER

# ROOT should be the parent of the .ecryptfs and .Private folders

sudo mkdir -p $TARGET
cd $ROOT

echo Type your password:
PASS=$(ecryptfs-unwrap-passphrase .ecryptfs/wrapped-passphrase | sed s/Passphrase:\ //)
SIG1=$(head -n1 .ecryptfs/Private.sig)
SIG2=$(tail -n1 .ecryptfs/Private.sig)

echo Passphrase:
echo $PASS
echo Signatures:
echo $SIG1
echo $SIG2

echo Should be empty:
sudo keyctl clear @u
sudo keyctl list @u

echo Do not type anything:
echo $PASS | sudo ecryptfs-add-passphrase --fnek

echo Sould have signatures:
sudo keyctl list @u

echo Mounting $ROOT on $TARGET...
sudo mount -t ecryptfs -o key=passphrase,ecryptfs_cipher=aes,ecryptfs_key_bytes=16,ecryptfs_passthrough=no,ecryptfs_enable_filename_crypto=yes,ecryptfs_sig=$SIG1,ecryptfs_fnek_sig=$SIG2,passwd=$(echo $PASS) .Private $TARGET

ls $TARGET

I put it in /mnt/sda_backup/home/$USER , that is /home/$USER in the chroot. Remember to check that USER is set to the proper username for the EcryptFS stored home directory you want to access.

There, now you can access everything from the outside world through:

ls /mnt/sda_backup/mnt/$USER

I thought that especially the EcryptFS-part was cumbersome so I thought I'dd write a post where all details come together.

If you want to use encryption under Linux, I strongly suggest using Luks instead, it's a bit harder to get your head around in the beginning since there is no integration in for example Ubuntu, but it is much nicer to use.

Happy hacking,
Daniel

Friday, November 21, 2008

Spotify, Guitar Pro, Wine = Messed up fonts

Some context, I got an invite to Spotify from a friend. They say that Spotify works under Wine in Linux so I decided to try it out.

The program works very well, it's very snappy and well thought out. I really like the service, it makes it easy to find new music and to share it with other people (who also needs to have Spotify or something similar of course).

There was only one issue. Spotify allows you to play their Radio, which is pretty much a shuffle over the genre you have specified and the years you have specified.

However, In wine I got bad fonts for all the buttons on that page, instead of Roman letters, I got musical notation. I thought that this was a bug I could live with until I tried it at another Linux installation which did not have this bug. So, how can this happen?








Well, it is a font-issue in Wine. Wine creates a small filesystem that looks like a Windows-filesystem with a few necessary catalogs. Like for example windows/Fonts. Your programs are then installed into this mini-filesystem into for example the "Program Files" directory.

Now for the bug I encountered. Or, I don't think that it is an actual bug per se, just an unwanted effect.

Wine typically stores its fonts in /usr/share/wine/fonts or in /usr/share/fonts/wine.
Now, if you install your own fonts, they go into the directory windows/Fonts in your mini-filesystem. This is also where all your Windows-programs will store its fonts as they think they are running on Windows.

The issue comes from the ordering of locations to search for fonts. Wine first checks the windows/Fonts directory and if it can't find the font there, then it will go to its own fonts.
So if any of your Windows-programs have installed fonts there (in my case, it was Guitar Pro which had installed a musical notation font) Then that will be searched first.

I got the issue, I believe, because the font requested by Spotify wasn't in my windows/fonts directory, and then it wasn't found among Wines core-fonts, so it defaulted to take the first font it could find - which was the Guitar Pro font.

The fix?

$ cp /usr/share/wine/fonts/tahoma.ttf ~/.wine/drive_c/windows/Fonts/a.ttf

Saturday, November 15, 2008

My hate for tapping and an introduction to modifying drivers in Ubuntu

First, a little background. On most laptops you have a touchpad which you can use to move your mouse-pointer around. Then someone came up with the twisted idea that you could use the touchpad to click on stuff. I have always turned this off, both when sitting on Windows and Linux. But for some reason, the driver-makers seem to conspire against me. In windows, the setting won't get stored on my laptop, so after every reboot, it is turned on again. In linux, well, there are a few occasions when it just turns itself on again. Not to mention that if some tool decides to modify your xorg.conf, you probably will get it turned back on again.

Some time ago, I got really tired of this and decided to download the source for the linux-driver and remove the possibility to tap on the touchpad alltogether. :)

On ubuntu you just run:

$ apt-get source xserver-xorg-input-synaptics

To download the source.
When you have downloaded it, make a copy of it, in this post I will call them $ORIG and $COPY.

The reason for this is that in Ubuntu they package unmodified source for a particular release of the software and then they have a set of patches that they apply when they build the packages. So what we want to do is to create a patch that will apply cleanly just as if it had been a part of the Ubuntu release.

Some things about structure of the source package, if you go inside $COPY, you can see a debian catalog, this is where patches and configuration is stored, you can also see a src, for source. These are the two catalogs that we will be looking at.

Let's begin by finding what it is we want to change. You can turn off tapping by setting MaxTapTime to 0 in xorg.conf, so we begin by finding where this is read with:

$ grep MaxTapTime $COPY/src/*

So, it is in synaptics.c?
This line:
pars->tap_time = xf86SetIntOption(opts, "MaxTapTime", 180);
Let's do a google search on what xf86SetIntOption is supposed to return.
So, it returns the integer that is read from xorg.conf. This will be a quite easy patch then, since we always want this value to be 0.

So, let's set everything up and start working. Begin by applying all patches that are shipped.
While standing in $COPY, run:

$ for file in `ls debian/patches`; do patch -p1 < debian/patches/$file; done"

Now it is ready for our patch. Do a:

$ cp synaptics.c synaptics.c.orig

We need the original file so we can create a patch. Open the synaptics.c file in your favorite editor (emacs) go to the pars->tap_time line and change it to: pars->tap_time = 0;.

Now it's time to create the patch, quit the editor. Run:

$ diff -Naur synaptics.c.orig synaptics.c > $ORIG/debian/patches/107_no_more_tapping.patch

Add the new file to $ORIG/debian/patches/series

Now, modify the head of the patch to have the same style as the others. It should look something like this:

$ head -n5 107_no_more_tapping.patch

Index: xfree86-driver-synaptics-0.15.2/src/synaptics.c
===================================================================
--- xfree86-driver-synaptics-0.15.2.orig/src/synaptics.c 2008-11-15 13:35:36.000000000 +0100
+++ xfree86-driver-synaptics-0.15.2/src/synaptics.c 2008-11-15 13:36:07.000000000 +0100


After you have done this, it's time to build the new deb by running:

$ apt-get build-dep xserver-xorg-input-synaptics

This will install everything you need to have in order to compile the package.

Then go to $ORIG and run:

$ dpkg-buildpackage -rfakeroot

This will create the deb for you and put it in the directory above. To install your new tap-free driver, just run:

$ dpkg -i xserver-xorg-input-synaptics_0.15.2-0ubuntu7_amd64.deb

Be aware though that when a new version is released, it will by default overwrite your patched binary.. but just keep the patch and do the same procedure then.

And for a time, it was good.

Tapping was no more.

Friday, November 14, 2008

Fun with moab/maui

So, some context, I work a lot with scheduling of computational jobs.

That means that we have a lot of jobs/programs that need to be scheduled on different resources. We do this with the scheduler moab. In order to visualize how resources are utilized we plot this into graphs.
I got this idea a few weeks ago, wouldn't it be quite fun to draw pictures in these graphs by creating reservations?

Said and done, I sat down and wrote a small python-script that takes an ascii-art image and creates reservations that you can then put into your system. :)

A text image example can be found here: image.txt

And the python script is here: generate_allocation_image.py

The result after running it a few times with different offsets;



Well, you got to do something with your spare time ;)