The A20.

Standard

Hola mi amigos! Life’s been going smoothly since my last article. After a long time, I did a brilliant hack that I’d love to share. Whats so brilliant about it? Well, I got an Allwinner A20 based Android tablet and I dual booted Ubuntu 12.04 LXDE on it. Very hacky, very time consuming but you’ll get to learn about the system quite a bit.

Well, lets start with a rooted Android tablet running on an Allwinner A20 processor. This processor is based on ARMv7 core. Assuming that your tablet is rooted (check XDA for rooting methods or just Google it. I personally used vRoot to root my LG E450), lets pull out a file from the device. On a Linux box (mine is Mint Nadia) type:

# adb devices
// prints a list of attached devices. Hopefully, you have one device attached.
# adb shell

mkdir /mnt/tmp
mount -t vfat /dev/block/nanda /mnt/tmp
exit

# adb pull /mnt/tmp/script.bin

Now, for the starters, what is this “script.bin“? It is the device configuration file. Allwinner does this because this is a smart way of tweaking the Linux kernel without having to recompile the kernel. This is very cool. You can tweak video resolutions, general purpose IO pins etc. I’ll R&D some more into this and let it out here.

The Allwinner A20 is based on the ARMv7, so to compile, rather cross compile, the code on some other (x86) architecture, you’ll need the GCC ARM compiler and some other tools. This will install the GCC compiler and some other tools (that you may already have).

# apt-get install gcc-4.7-arm-linux-gnueabihf ncurses-dev uboot-mkimage build-es

Allwinner has their own bootloader that they use in their SoCs. It sets up a basic a structure to load and boot a Linux kernel. ON A SD CARD! So now, we clone the git of U-Boot and manually build the source. Pretty. Fucking. Cool.

# git clone -b sunxi https://github.com/linux-sunxi/u-boot-sunxi.git

got it? Now, cross compile! ūüėÄ

# make a20-olinuxino_micro ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-

The interesting thing is a20-olinuxino_micro. Open the cloned directory and surf to boards.cfg. Open it. There you will see how many ARM processors U-Boot supports. This parameter to the `make’ command says that the compiler should compile the code according to the A20 architecture.There are many other boards (RPi being eyed upon) that you can hack. If you have an ancient laptop like mine, you can go and have like 15 cups of coffee and roam around for a while and stretch so much that you tear yourself apart. Because compilation will take time.

Allwinner has their own version of embedded Linux called SunXI. We have to compile it to generate a bootable image (uImage) that will boot the actual kernel. The booting process is as follows: (please correct me if I’m wrong)

  • U-Boot loads the `uImage’ from the SD card to RAM
  • uImage deflates the actual kernel and sets up parameters to boot the kernel.
  • The kernel is loaded from an ext3 partition on the SD card and since it is (will be) compiled for ARMv7, it just works.

Clone Allwinner’s SunXI. Fire this command:

# git clone https://github.com/linux-sunxi/linux-sunxi

Now, again we cross compile. Before that, we have to tell the kernel that we are going to compile it specifically for the A20 architecture. If you have compiled kernels before you’ll know that arch//configs has configuration required for many architectures. Open arch/arm/configs. There you will see many device configuration files. They define basic kernel setups to compile kernel for a particular processor. For the A20 processor, we have to use sun7i_defconfig. It will set up the kernel according to A20 processor. Again, I’ll play with it in coming weeks and let you know what it actually is. Fire this command. I assume that your PWD is the cloned directory (linux-sunxi).

# make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- sun7i_defconfig

We have to now compile the kernel image. The GCC compiler is very efficient. You can specify number of processors to be used while compiling the source. Again assuming that your PWD is linux-sunxi, fire this:

# make -j2 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- uImage modules

The `-j2 ‘ option tells the compiler that I have two cores in my host processor and it should use both the cores. If you have 4 cores, you can say -j4… fucking awesome. The above command compiles the kernel and generates kernel image and all the essential modules that the kernel requires. Again, go have some coffee and take a walk with your girl… this will take time. Much time.

That being done, we have to now install the compiled kernel modules. Fire off:

# make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j2 INSTALL_MOD_PATH=out modules_install

This will install the compiled modules in a directory called “out”. If you open this directory, you’ll see that the compiled modules and firmware are generated. We will copy these files to a stock Ubuntu kernel (hang on!).

Buy/get/borrow/steal a 4-8GB SD card. We will partition the card and install the kernel in it. To partition the card, insert it into your laptop’s (I have a laptop so…) SD/MMC reader and do: (on my Mint Nadia, the SD card is shown as /dev/mmcblk0, type fdisk -l to see what your SD card is called in /dev)

# fdisk /dev/mmcblk0
Command (m for help): n
Partition type:
p (primary...)
e (extended...)
Select (default p): p
Partition number (1-4, default 1):
Using default value 1
First sector (2048-7744511, default 2048):
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-7744511, default 7744511): +16M

This partition will later be formatted as a vfat partition and will save the script.bin and the uImage. Similarly, create another partition that will store Ubuntu Linux. You may optionally create a swap space… I didn’t so I skip this step.

Command (m for help): n
Partition type:
   p   primary (1 primary, 0 extended, 3 free)
   e   extended
Select (default p): p
Partition number (1-4, default 2):
Using default value 2
First sector (34816-7744511, default 34816):
Using default value 34816
Last sector, +sectors or +size{K,M,G} (34816-7744511, default 7744511):
Using default value 7744511

Cool… write the changes to your card using the `w’ command in fdisk prompt. We now format the partitions. First partition will be vfat and second will be ext3.

Note that after partition, my sd card looks like this:

Disk /dev/mmcblk0: 7948 MB, 7948206080 bytes
4 heads, 16 sectors/track, 242560 cylinders, total 15523840 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

        Device Boot      Start         End      Blocks   Id  System
/dev/mmcblk0p1            2048       34815       16384   83  Linux
/dev/mmcblk0p2           34816    15523839     7744512   83  Linux

To format the partition then, I fire the command:

# mkfs.vfat /dev/mmcblk0p1 // format partition 1 to vfat
# mkfs.ext3 /dev/mmcblk0p2 // format partition 2 to ext3

Awesome, now lets dd. We dd because to write the bootloader (U-Boot) we have to copy data block by block. We are not copying a file, we are actually, in a way, writing the firmware on the SD card.

# dd if=u-boot-sunxi/u-boot-sunxi-with-spl.bin of=/dev/mmcblk0 bs=1024 seek=8

When you compile U-Boot, you get “u-boot-sunxi-with-spl.bin”. No I know not what it really does (to be honest, I don’t know what SPL is). Note that I’m NOT writing it to a partition (its in bold).

Now download Ubuntu LXDE from here. Mount partition 1 and copy script.bin and uImage.

# mount /dev/mmcblk0p1 /media/code-ninja/uboot
// I assume that you're in your Root Home directory and script.bin is in PWD
# cp {linux-sunxi/arch/arm/boot/uImage,script.bin} /media/code-ninja/uboot

Now mount the second partition and untar the downloaded Ubuntu 12.10 in this partition. You now have a ready to boot Ubuntu on the SD card. Remember that you installed modules in a directory called “out”? Copy everything from that directory to Ubuntu’s “/lib” like:

# cp -r linux-sunxi/out/ /media/code-ninja/Root/lib // I call my Ubuntu ext3 partition "Root"

Now the hackiest part. We have to configure the installed OS before we can start using it. This version of Ubuntu is devoid of any UI or other good things. We will chroot into it and install. But the catch is, it is compiled for ARM architecture… how will you run it on a x86 machine?! The solution is: qemu-arm-static.

This is a static version of the QEMU virtual machine and is used to run a command line OS without having to start the full-fledged emulator. From your host machine, do this:

# cp /usr/bin/qemu-arm-static /media/code-ninja/Root/usr/bin

Now, lets set up a basic chroot environment and login to our Ubuntu. Lets hack:

# mount -t proc /proc /media/code-ninja/Root/proc
# mount -t sysfs /sys /media/code-ninja/Root/sys
# mount -o bind /dev /media/code-ninja/Root/dev
# mount -o bind /dev/pts /media/code-ninja/Root/dev/pts
# chroot /media/code-ninja/Root
root@GeniuSisMe:~/# // I'm in!

Now just install whatever you want (language packs, browser… make your pick). You can install LXDE by saying:

# apt-get install lxde-core // I haven't done this, so no GUI for me... yet.

After you’re satisfied with your build, plug in the SD card into your tablet and boot to enjoy Ubuntu!

Following are the screen shots: Thats an Allwinner Pad.

Linux booting on Android A20 tablet.

Linux booting on Android A20 tablet.

The signature Penguins of Linux! Pretty cool, eh?!

Tell me how your dual boot goes! Till then… Sionara!

May the force be with you.

D.

Advertisements

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