Sunday, August 28, 2011

Custom OpenEmbedded distribution based on Angstrom

Angstrom distribution is similar to Ubuntu or Fedora but it is specifically meant for embedded devices. Angstrom uses the OpenEmbedded system to build their distributions.

If you want a ready made image for your embedded device you can use their online builder available here.

I recently faced a situation where I had to enable SPI driver in Angstrom distribution for beagleboard. For that I had to custom compile the Linux kernel with the McSPI module enabled since it was not enabled in the default builds.

Step 1:

Create a folder in your home directory called "openembedded"
$mkdir ~/openembedded
$cd ~/openembedded

Step 2:

Download the setup scripts for Angstrom using git
$git clone git://git.angstrom-distribution.org/setup-scripts
$cd setup-scripts

Step 3:

Start the build process for beagleboard. This will download the "bitbake" which is only a tool used to build packages and "openembedded" system which provides the "recipes" of the packages for the "bitbake" tool.
./oebb.sh config beagleboard
Note: Replace beagleboard with your embedded machine name. Also note that "openembedded" git download is more than 700 MB.

Step 4:

Load the script file created in the previous step. You need to do this everytime you want to build packages from a new terminal, or you can add this line to the ~/.bashrc file
$source ~/.oe/environment-2008

Step 5:

Build your first package the famous "nano" command line editor
$bitbake nano

Now, the real thing is to build the kernel image from source
$bitbake virtual/kernel

Links :
http://www.angstrom-distribution.org/building-angstrom

Tuesday, August 23, 2011

Compiling Linux kernel for any CPU architecture

You can compile Linux kernel for any architecture including x86/arm/sparc/mpis etc. Inside the "arch" directory of the root kernel source tree you will find the list of the architectures supported by Linux.



For example to configure the Linux kernel for the "arm" architecture, from the root directory of the linux kernel sources tree do

$make menuconfig ARCH=arm

Note the ARCH=arm parameter in the above command. This will bring up the kernel configuration for the "arm" architecture. Similarly be replacing the ARCH parameter with name of architecture from the "arch" folder you can configure the kernel for that particular architecture.

Another example, for the "mips" architecture you can do

$make menuconfig ARCH=mips

Monday, August 22, 2011

Compiling vanilla Linux kernel in Ubuntu

This article describes how to compile a kernel downloaded from kernel.org in Ubuntu. We are going to compile the latest kernel as on today which is linux-3.0.3. Lets get started...

1. Pre-requisites: Install the following packages
$sudo apt-get install kernel-package libncurses5-dev fakeroot wget bzip2

2. Create a directory in your home directory for compilation (it is not recommended to this work inside /usr/src)
$mkdir ~/linux-kernel
$cd ~/linux-kernel

3. Download and extract the linux kernel sources from kernel.org
$wget http://www.kernel.org/pub/linux/kernel/v3.0/linux-3.0.3.tar.bz2
$tar jxvf linux-3.0.3.tar.bz2
$cd linux-3.0.3
Note : You can apply any kernel patches at this stage if you want. We will skip this step.

4. Configure the kernel as per your requirements. There are many ways to do this, but the recommended method is to use your current configuration to start from.
$cp /boot/config-`uname -r` ./.config
You need to update your old configuration and bring it to the current kernel source structure.
$make oldconfig
It will ask a few questions which relate to updates that are made in the kernel sources. If you dont know just press "ENTER" to select the default options.

Now, you can customize the kernel configuration as per your requirements by doing
$make menuconfig
This will open up a ncurse based kernel configuration tool. When you are done, save and exit.

5. Build the kernel
$make-kpkg clean
$fakeroot make-kpkg --initrd --append-to-version=-custom kernel_image kernel_headers 
Here you can specify your own version string by changing the "--append-to-version=" option in the previous command. Your string MUST always start with a "-". In our case it is "-custom" so the kernel will be called "3.0.3-custom"

It will take some time to build the kernel, so have a cup of coffee till then :)

6. Once the kernel has been compiled there will be two .deb packages in the parent directory. In our case they are :
linux-headers-3.0.3-custom_3.0.3-custom-10.00.Custom_i386.deb
linux-image-3.0.3-custom_3.0.3-custom-10.00.Custom_i386.deb

Go back to the parent directory and list the files to locate the two .deb packages
$cd ..
$ls

7. The final step is to install the new kernel by using "dpkg" command. You need to be sudo to install the packages.
$sudo dpkg -i linux-image-3.0.3-custom_3.0.3-custom-10.00.Custom_i386.deb
$sudo dpkg -i linux-headers-3.0.3-custom_3.0.3-custom-10.00.Custom_i386.deb

This will also automatically copy the kernel and initrd images to /boot, copy the modules to /lib/modules and also add a entry in the GRUB boot loader. Now you are ready to boot into your new kernel ! Just restart the machine and select the new kernel from the GRUB menu. If there is any problem with booting you can go back to the old kernel which is still there in the GRUB menu list.

8. Once you have booted into the new kernel, you can verify the kernel version by
$uname -r

Also as a bonus you can use that deb file generated - in any other Ubuntu machine for installing the new kernel.

Note : You can also use the -j option to specify the number of threads to use to compile the kernel.
$fakeroot make-kpkg --initrd --append-to-version=-custom kernel_image kernel_headers -j 3
Links :
http://www.howtoforge.com/kernel_compilation_ubuntu

Friday, August 19, 2011

How to install ARM Debian on Ubuntu using Qemu

1. Install the "qemu" and "qemu-system" packages

$sudo apt-get install qemu qemu-system

2. Download the debian initrd and kernel image for ARM

$wget http://ftp.de.debian.org/debian/dists/lenny/main/installer-armel/current/images/versatile/netboot/initrd.gz
$wget http://ftp.de.debian.org/debian/dists/lenny/main/installer-armel/current/images/versatile/netboot/vmlinuz-2.6.26-2-versatile

3. Create a 10 GB disk image to be used as harddisk

$qemu-img create -f raw armdisk.raw 10G

4. Start qemu

$qemu-system-arm -M versatilepb -kernel vmlinuz-2.6.26-2-versatile -initrd initrd.gz -hda armdisk.raw -append "root=/dev/ram" -m 256 

This will start the debian installer for ARM platform.


At the end of installation you will get a error message that boot loader cannot be installed - just ignore it.

5. Once it has finished installing next step is to copy the vmlinuz and initrd from the installed debian system for booting.

Create a mount point:
$sudo mkdir /mnt/armdeb

Mount the harddisk image:
$sudo mount -o loop,offset=32256 armdisk.raw /mnt/armdeb

Copy the kernel and initrd image:
cp /mnt/armdeb/boot/vmlinuz-2.6.26-2-versatile .
cp /mnt/armdeb/boot/initrd.img-2.6.26-2-versatile .

Unmount the harddisk image:
$sudo umount /mnt/armdeb

6. Finally boot into the newly installed ARM debian system:
$qemu-system-arm -M versatilepb -kernel vmlinuz-2.6.26-2-versatile -initrd initrd.img-2.6.26-2-versatile -hda armdisk.raw -append "root=/dev/sda1"

Monday, August 15, 2011

Build your own cross compilation tool chain in Linux

This article describes how to setup your machine to cross compile programs for some other architecture. This involves setting up is called as a "cross compile tool chain". We are going to use crosstool-ng for this purpose. It is a collection of scripts that will download, compile, install the entire tool chain required for cross compiling. We will create a "ARM" based tool chain in this example.

We will be installing the toolchain in the "cctools" directory inside our home folder. Also note that all commands are run as normal user unless otherwise mentioned. Let us create the directory for the same.

$cd
$mkdir $HOME/cctools
$cd $HOME/cctools

Now, go to http://crosstool-ng.org and download and extract the stable version of the script.

$wget http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.12.0.tar.bz2
$tar jxvf crosstool-ng-1.12.0.tar.bz2
$cd crosstool-ng-1.12.0

You also need to install the following packages (run as root):
$sudo apt-get install libtool automake texinfo flex bison subversion cvs expat libexpat1-dev python-dev libncurses5-dev

Once this is done, we will create a separate build directory.
$mkdir $HOME/cctools/build

Now, let us configure crosstool-ng to build in that directory.
$./configure --prefix=$HOME/cctools/build

Compile and install crosstool-ng.
$make
$make install
This will install crosstool-ng inside the build directory that we specified. We need to add this build directory to the PATH shell variable.
$export PATH="${PATH}:$HOME/cctools/build/bin"
This has completed the installation of the crosstool-ng.
(Note : You can add this to your ~/.bashrc file for future use)

Next step is to setup the system for cross compilation. We will create a separate directory for the "ARM" tool chain.
$mkdir $HOME/cctools/arm
$cd $HOME/cctools/arm

Now run the crosstool-ng configuration script in this directory.
$ct-ng menuconfig

This will show you a menu driven interface for selecting the target architecture, path for download and installation of the tool chains, architecture specific optimization and features, etc. In this configuration window change the relevant options for "ARM" based tool chain.

You can directly copy a predefined configuration file for the architecture from the $HOME/cctools/crosstool-ng-1.12.0/samples folder and then run the above "$ct-ng menuconfig" tool.

eg :
$cp $HOME/cctools/crosstool-ng-1.12.0/samples/arm-cortex_a8-linux-gnueabi/crosstool.config .config

Also you need to change the prefix directory where you want the tool chain installed. We will build it inside the build directory where we initially installed the crosstool-ng.
Paths and misc options > Prefix directory : ${HOME}/cctools/build/${CT_TARGET}



Once this is done press "ESCAPE" and save the configuration file. The file is saved as ".config", you can even hand edit this file directly if you want.

Now the final step is download, extract and build the tool chain. All of this is done automatically by the crosstool-ng by executing:
$ct-ng build
It downloads around 200MB source files and takes around 1 hour on a "3 Ghz dual core with 4 GB RAM" machine for compilation. The source files are downloaded in the ".build" directory. Once this completes the tool chain is available in the ${HOME}/cctools/build/ directory, the folder name is dependent of the architecture selected. You can add this to the PATH shell variable.
$export PATH="${PATH}:$HOME/cctools/build/arm-cortex_a8-linux-gnueabi/bin"
(Note : You can add this to your ~/.bashrc file for future use)

Let us cross-compile one sample "Hello World" C program that will execute on a "ARM" machine. The C program filename is "sample.c"
$arm-cortex_a8-linux-gnueabi-gcc sample.c -o sample -Wall
This will compile the executable file "sample" for the "ARM" architecture.