Jan 21, 2013

Compile Android 2.3.3 in Slackware 14

I. Introduction:
Recently I decided to change my linux distro from ubuntu to slackware. The installation process is nice and smooth. After I install slackware, I decided to download the android 2.3.3 source and compile myself. I have done it before in ubuntu 10.04, so I told to myself how hard could it be. However I was wrong, compiling android in slackware 14 is incredibly annoying. Most of the problems are caused by gcc and perl version mismatch. Some people might say, just downgrade/upgrade your gcc/perl version and it should be fine. I know that, but changing gcc/perl version in your system might cause some problems and I don't want to take that risk. (btw, recompile gcc is very time consuming in my computer. Hardware sucks) 
Because the above reason, I decide to compile the android 2.3.3 without downgrade any tools and also to write the whole process down to remind myself how I do it.

II. Environment:

  • Linux Distro : Slackware 14 x86_64( with multilib support )
  • gcc version : 4.7.1
  • make version : 3.82
  • perl version : 5.16
  • git version : 1.71
  • python version : 2.73

Just a clean install of slackware 14.
As for multilib support just check out Alien BOB wiki and follow the instructions that wiki mentioned. 
P.S you should at least have >2GB of RAM or the building process may failed. 

III. Compiling Steps:
This post is mostly focus on how to solve the version mismatch problems; therefore, I will not cover how I setup the build environment in this post. (Most libraries that required to build android are already installed by the Slackware 14 clean install)
After you follow the ASOP instructions and install all the necessary packages, it is time to type make command. (I highly recommend that use 'make -j1' instead of 'make -j8' )

1. GCC version mismatch:
The following is an example of how this kind of error message look like and the general solutions of how to solve this kind of problems. Figure 1 shows how this kind of error message looks like. There are two ways to solve this kind of problem. 
The first one is add "this->" in front of all the variables that appear in the error message. However, in the entire building process, you will be very annoying adding this pointer in front of all the errors.
The second method is to add  "-fpermissive" flag in the makefile. More precisely add "-fpermissive" to LOCAL_CFLAGS in Android.mk. This method is more reasonable. 
During the whole building process, there are several Android.mk files that need to be modified (adding "-fpermissive" flag)


[figure 1] gcc version mismatch error message
[Figure 2] Add "-fpermissive" after the LOCAL_CFLAGS in the Android.mk

2. perl Switch module problem:
Switch.pm is deprecated in perl 5.16, therefore the solution is simple, patch the "external/webkit/WebCore/dom/make_names.pl". Figure 4,5,6 show some modification of this file. 
[Figure 3] Can't locate Switch.pm
[Figure 4] comment use Switch
[Figure 5] use if else instead of switch case

[Figure 6] delete the "-P" flag from preprocessor
IV. Conclusion:
After the above steps, the building process should be fine and you can see the image file in the out directory.
I also make a diff file which you can download from here: http://pastebin.com/RCfB5irk
Just download the file and type:
patch -p1 < patch_file_name.patch
Enjoy :)

Linux Kernel 1: How to Compile Linux Kernel

I. Introduction:
This post is the first post for linux kernel hacking. Before you can dig into linux kernel source you should first learn how to build a kernel yourself.
There are many distributions out there, and I prefer to use Slackware 14, gentoo or debian (not dibian based distro such as ubuntu, mint). The reason I recommend to use these two distro is because that most modern distributions have changed so many linux codes that may confused you while your are tracing linux code.

II. Environment:
  • Linux Distro: Slackware 14 x86_64
  • kernel version: 3.2.37
  • gcc version: 4.7.1
III. Contents:
1. pre-requirement:
The first thing you should do is download the kernel source that you want to build. The kernel source file can be found in : http://www.kernel.org/pub/linux/kernel/.
In my case, "linux-3.2.37.tar.bz2". Just extract the file and put it into the directory that you want. I put the source code in "$HOME/kernel/".

2. config:
Before building the kernel, you have to config it first.  type "make help" and you can see a list of options. In this part, we just focus on the config sections.
The following  are some options that are commonly used.

config          - Update current config utilising a line-oriented program
menuconfig      - Update current config utilising a menu based program
xconfig         - Update current config utilising a QT based front-end
gconfig         - Update current config utilising a GTK based front-end
oldconfig       - Update current config utilising a provided .config as base
localmodconfig  - Update current config disabling modules not loaded
localyesconfig  - Update current config converting local mods to core

The description is very self-explained therefore I'm not going to explain it. Just a quick note, if you prefer the GUI interface, type "make xconfig/gconfig" which will give you gui interface to config the kernel. In my case I use "make localmodconfig" which will set the config file according to your system modules.

 you can also use "gcat /proc/config.gz > .config" if your previous kernel has enable the IKCONFIG  and IKCONFIG_PROC flag. This will copy the previous kernel configuration to your current kernel source. After you finished the above command you can still type "make oldconfig" if you are using a newer kernel. (The newer kernel may have some new features )
Thank you +Eric Garland. :)

3. build the kernel:
If this is the first time you compile this kernel Type "make all -j8" to compile the kernel. The "make help" output tell us that the make install will build the target marked * and the default one is "vmlinuz" and "modules".
However, if u have compiled the kernel before and there is no new featured that is added in the config file.You can type "make vmlinuz -j8" instead. It will only build the vmlinuz and will not build the modules.
If you have add a new modules or edit the modules source code you can type "make modules -j8" to only compile the linux modules.
P.S Compiling the linux kernel may take some time according to your hardware. (get a cup of coffee or watch a movie :P)

4. Install the modules:
If this is the first time you build the linux kernel: type "sudo make modules_install". If your haven't modify any kernel modules or add a new one in the config file, this step can be skiped.

5. Install the kernel:
Instead of typing "make install" I prefer using the following command.

sudo cp arch/x86_64/boot/bzimage /boot/vmlinuz-3.2.37
sudo mkinitrd -c -k 3.2.37 -m ext4 -f ext4 -r /dev/sdaN -o /boot/initrd-3.2.37.img

More detailed about mkinitrd command, type "man mkinitrd" or check out this link: http://mirrors.slackware.com/slackware/slackware-11.0/extra/linux-

6. Update your bootloader:
Since I'm using slackware and the default bootloader of slackware is lilo, so I have to edit the /etc/lilo.conf. After modified the /etc/lilo.conf type "sudo lilo".

7. Command Walk through:

        // if this is the first time you compile the kernel
make mrproper;
// if this is the first time you compile the kernel or want to add some new features to your kernel.
make localmodconfig/menuconfig/xconfig/gconfig;
make all && make modules_install; // if this is the first time you compile the kernel or adding new stuff to the
make vmlinuz; // if you just change the kernel source
make modules && make modules_install; // if you have add a new module in config file or modify the module source code
cp arch/x86_64/boot/bzimage /boot/vmlinux-3.2.37
mkinitrd -c -k 3.2.37 -m ext4 -f ext4 -r /dev/sda2
-----update your bootloader----
echo "done";

IV Conclusion:
This is basically how to compile a linux kernel. I will talk about some more configuration and some tools to help you trace the linux code. Happy Hacking.