Home page of this blog

Monday, October 4, 2010

Ubuntu Maverick 64bit Kernel Compilation

Introduction

After installing Ubuntu Maveric release candidate, I tried to play some movies. The movies were getting stuck. I tried to open windows and alt-tab windows. Everything seems to get stuck!

Why? The reason I believe lies in the way Ubuntu 64 bit kernel is built. 64 bit ubuntu kernel timer frequency is just 100 HZ

100 HZ is excellent for running inside cloud or virutalized environments, but 100 HZ  is unsuitable for desktop activity or games. Graphics drivers demand a very high timer frequency eventhough kernel has moved on to tickless. Nvidia proprietary kernel module requires 1000 HZ to play games or render graphics without a lag (this is based on my observation of how the movies lag though I have a very powerful processor i7 and a very powerful graphics card nvidia gtx 460).

So I wanted to get a kernel which has 1000 HZ kernel frequency. I did not find one and I am doing compilation myself.

I found the following blog extremely useful for kernel compilation

http://blog.avirtualhome.com/2010/07/14/how-to-compile-a-ubuntu-2-6-35-kernel-for-lucid/

Unfortunately, the article is using git and I don’t have patience to download 700+ MB of git content and package content just to compile a 88 MB kernel.  The answer to this comes from the same blog which explains kernel compilation without using git, but written for ubuntu intrepid which is nearly 2 years back

http://blog.avirtualhome.com/2008/10/28/how-to-compile-a-custom-kernel-for-ubuntu-intrepid/

The current method I used, fuses both the methods and compiles without using git.

Here is a how to of kernel compilation which I did exactly without using git for compiling. This may help someone with a similar problem, hence this document

This article only tells how to compile 64bit kernel and does not bother to explain 32 bit kernel compilation.

Step 1: Install all dependencies to compile kernel


The following command will install all the dependent packages needed for compiling a linux kernel.



sudo apt-get install fakeroot build-essential crash kexec-tools makedumpfile kernel-wedge libncurses5 binutils-dev libelf-dev libdw-dev libnewt-dev libncurses5-dev



Install the following separately (this avoids pulling all recommended packages, which are huge)



sudo apt-get  --no-install-recommends install asciidoc xmlto



Ensure none of the dependent packages are missing by running the following command.

sudo apt-get build-dep linux


Step 2: Get the kernel source code


Create a directory called Builds and change into the created directory. This will make the task of handling the kernel builds pretty easy.

mkdir Builds
cd Builds

The following command helps the kernel source to be fetched and extracted in the current directory. In this case this is Builds directory. See that the command is executed as a normal user only (without sudo prefix)

apt-get source linux-image-$(uname -r)

Step 3: Create a copy before compiling


cp linux-2.6.35 linux -r

Always use the copy instead of the original source directory. In case there is an error and not recoverable, delete the directory linux and recreate it using above command.

Step 4: Create a new config


Change into the copied linux directory.

cd linux

Copy the generic flavour of the kernel and give the name of your processor for the new flavour. See that I am giving i7

cp debian.master/config/amd64/config.flavour.generic debian.master/config/amd64/config.flavour.i7

fakeroot debian/rules clean

Change the scripts permissions to make them executable

chmod -Rv +x debian/scripts/

fakeroot debian/rules updateconfigs

The following will bring up the kernel configuration screen for whichever configuration we give Y to edit. In this case I gave Y to config.flavour.i7

fakeroot debian/rules editconfigs

The following are the important configuration changes I made

  • Changed
    • Processor type and features --> Timer frequency --> 1000 HZ
    • Processor type and features --> Processor family --> Core 2/newer Xeon
  • Unticked(deselected)
    • Processor type and features --> Support for extended (non-PC) x86 platforms
    • Device drivers --> Staging drivers --> Nouveau (nVidia) cards


Step 5: Changing abi files before compilation


Copy the generic abi for the custom flavour. In this case it is as follows

cp debian.master/abi/2.6.35-22.34/amd64/generic debian.master/abi/2.6.35-22.34/amd64/i7
cp debian.master/abi/2.6.35-22.34/amd64/generic.modules debian.master/abi/2.6.35-22.34/amd64/i7.modules

Add i7 (or whatever flavour name we gave) to the getabis file under debian.master/etc/

sed -i s/getall\ amd64\ generic\ server\ virtual/getall\ amd64\ generic\ server\ virtual\ i7/g debian.master/etc/getabis

Add i7 (or whatever flavour name we gave) to amd64.mk file under debian.master/rules.d/

sed -i s/\=\ generic\ server\ virtual/\=\ generic\ server\ virtual\ i7/g debian.master/rules.d/amd64.mk

Make compiler aware of the flavour. change i7 to the flavour name we gave

cp debian.master/control.d/vars.generic debian.master/control.d/vars.i7

Edit the supported processor name in the above file. For e.g I changed to Core i7 from Generic

sed -i s/\"Generic\"/\"core\ i7\"/g debian.master/control.d/vars.i7

Step 6: Kernel Compilation


Since I wanted to optimize for core2 microarchitecture, I edited the following two files

arch/x86/Makefile
arch/x86/Makefile_32.cpu

In the file arch/x86/Makefile I made the following change




        cflags-$(CONFIG_MCORE2) += \
                $(call cc-option,-march=core2,$(call cc-option,-mtune=core2))

See the bolded mtune=core2, it was generic and I changed to core2

In the file arch/x86/Makefile_32.cpu I made the following change

cflags-$(CONFIG_MCORE2) += -march=core2 $(call tune,core2)

See the bolded march=core2, it was i686 and I changed to core2



Here is how I compiled for my flavour i7


Clean before building


fakeroot debian/rules clean

Independent package build


skipabi=true skipmodule=true fakeroot debian/rules binary-indep

Flavoured build


Build now, change CONCURRENCY_LEVEL=4 for quad cores and CONCURRENCY_LEVEL=2 for dual cores

CONCURRENCY_LEVEL=8 skipabi=true skipmodule=true fakeroot debian/rules binary-i7


Step 7: Installing newly built kernel


Change to previous directory, where all the build output as .deb files are created

cd ..

For e.g

sudo dpkg -i linux-headers-2.6.35-22-i7_2.6.35-22.35_amd64.deb linux-image-2.6.35-22-i7_2.6.35-22.35_amd64.deb

This will install all dkms modules which are already installed ( including nvidia proprietary driver if already installed from additional drivers)

restart (there should be a red colored power button in the top right corner of ubuntu, indicating that a restart is in due)







Enjoy