Showing posts with label build. Show all posts
Showing posts with label build. Show all posts

Tuesday, January 20, 2009

Building Fedora 10 kernel

_debug_compile
Preaparing the build environment:
In order to create the file system environment we need to run the following command where we want to build the kernel (If missing, install package rpmdevtools):
#/usr/bin/rpmdev-setuptree

Now, We are having the rpmbuild directory which contain the following directories : BUILD, RPMS, SOURCES, SPECS and SRPMS.

Note: the rpmdevtools was changed between fedora 9 and 10, in 9 we had to call fedora-buildrpmtree.
Other note: Some of the operations required root permissions, you can run it
as root or use "su", just remember that the rpmbuild directory is expected in the current user home directory and pay attention to the directory permission.

To set the build in a specific path (e.g. ~/rpmbuild) add the following to the ~/.rpmmacros file:
%_topdir %(echo $HOME)/rpmbuild #path to your custom
build dir

Download and install the kernel source:
Now, we should downoad the kernel source from http://kojipkgs.fedoraproject.org/packages/kernel, since my kernel version is 2.6.27.9-159.fc10.i686 I will download the file kernel-2.6.27.9-159.fc10.src.rpm

After the download completed, extract the rpm by typing (you can ignore the "warning: group mockbuild does not exist - using root" messages):
#rpm -ivh kernel-2.6.27.9-159.fc10.src.rpm

Preparing the build (in my case, for i686):
#cd rpmbuild/SPECS
#rpmbuild -bp --target=i686 kernel.spec

Building the kernel rpm:
Note: For this sample, I will build the kernel without any configuration changes.

Go to the build directory and start the rpm build.
#cd rpmbuild/BUILD/kernel-2.6.27/linux-2.6.27.i686
#make rpm
This is going to take some time .....

Creating the ram disk:
initrd image creation:
Since the mkinitrd function searching the built modules under /lib/modules/, I created a soft link from there to the place we have built the modules
(there must be more elegant way ...)
#cd /lib/modules/
# ln -s <build path>/rpmbuild/BUILDROOT/kernel-2.6.27.9-1.i386/lib/modules/2.6.27.9 2.6.27.9
#cd <build path>/rpmbuild/BUILDROOT/kernel-.6.27.9-1.i386/boot
#mkinitrd /boot/initrd-2.6.27.9.img 2.6.27.9

Installing the new kernel:
Now, We need to copy the generated files from the <build path>rpmbuild/BUILDROOT/kernel-2.6.27.9-1.i386/boot
directory to the /boot directory in the target machine:
initrd-2.6.27.9.img,System.map-2.6.27.9,vmlinuz-2.6.27.9,config-2.6.27.9

In the /etc/grub.conf file we need to add
an entry for the new kernel:
title myBuild (2.6.27.9)
root (hd0,0)
kernel /boot/ofer/vmlinuz-2.6.27.9 ro root=UUID=<your uuid> rhgb quiet
initrd /boot/ofer/initrd-2.6.27.9.img

Reboot the machine, choose the new kernel in the grub screen, and that it :-)




Saturday, November 15, 2008

Prepare and debug linux kernel with vmware 6

Vmware 6 includes kernel-debugging option which can replaced the kdb usage, Here's some explanation of this process:


The kernel source preparation:

Before the debugging we will have to prepare the source code and the debug image of the “debugged” kernel.


In my target machine (Inside the VMware) I'm using linux kernel 2.6.25.9-76.fc9.i686, first we will need to download the source code of this version and the vmlinux image file with debug symbols.
Thedownload location for this release is :
http://kojipkgs.fedoraproject.org/packages/kernel/2.6.25.9/76.fc9/
,
From there I downloaded the following files:

  • i686/kernel-devel-2.6.25.9-76.fc9.i686.rpm

  • i686/kernel-debuginfo-common-2.6.25.9-76.fc9.i686.rpm

  • i686/kernel-debuginfo-2.6.25.9-76.fc9.i686.rpm

  • src/kernel-2.6.25.9-76.fc9.src.rpm


Next, we need to install those packages, but before, We need to create the build directory tree for the source, The next command will create the SOURCES, SPECS and BUILD directories under ${HOME}/rpmbuild
#rpmdev-setuptree
Package installation (root user) :
# rpm -i <the packages>

Now, we need to prepare the source directories with all the patches:


# cd ~/rpmbuild/SPECS
# rpmbuild -bp --target=`uname -m` kernel.spec

The VMware 6 preparation:

Open the VMware configuration file (/etc/vmware/config) and add the following line:

debugStub.listen.guest32=1

Now, We will see the following line in the vmware log file, which mean that we are ready for debug:


VMware Workstation is listening for debug connection on port 8832.

The GDB preparation:

Instead of running the gdb with all the debugging arguments every time, we can edit the .gdbinit file with the initial configuration,
This file should be located either in the current directory or in the
home directory.
Add to the .gdbinit the following line to determine the file to launch:
file /usr/lib/debug/lib/modules/2.6.25.9-76.fc9.i686/vmlinux

Add the .gdbinit the following line in order to tell gdb to connect the remote host:


target remote localhost:8832

Now we will configure the source-code directories, After the previous
steps, the source code is located under ${HOME}/rpmbuild/BUILD/kernel-2.6.25/linux-2.6.25.i686 , to automatically insert all the sub directories, run the following command on bash:

#for file in `find ~/rpmbuild/BUILD/kernel-2.6.25/linux-2.6.25.i686 -type d`; do echo dir $file;done >> ~/.gdbinit

Debugging !!!

Now, all we need to do is to type
#gdb
(or ddd) In order to launch the debugger.


One issue I faced is that if I'm pausing the vmware guest machne to long, its shut down and I need to restart the guest OS again, still need to figure out this one ........

Sunday, October 26, 2008

"Hello World" kernel module

An Environment notes:
My kernel's module test environment is fedora core 9 with kernel version of 2.6.25.9-76.
In order to compile my module I had to download the development package of this kernel version and install it on my build/debug machine : http://kojipkgs.fedoraproject.org/packages/kernel/2.6.25.9/76.fc9/i686/

Now, the module source code :

// Start of code

#include <linux/init.h>

#include <linux/module.h>

// The following macro's can be found at the kernel include file linux/module.h
// with some other as MODULE_INFO, MODULE_ALIAS, MODULE_VERSION ....

MODULE_LICENSE("DUAL BSD/GPL"); // license applies to its code
MODULE_AUTHOR("Ofer Koren"); // Code author
MODULE_DESCRIPTION("hello-world module"); // Module description

// My “started” print function

void hello_func(void)
{
printk (KERN_ALERT "Hello World strated :-]\n");
}

// Module's initialization function
// The __init mean that this function can be dropped from the memory
// after the module is loaded

static int __init start_hello(void)
{
hello_func();
return 0;
}

// Module's exit function
// The __exit mean that this code should be called upon module exit only
static void __exit stop_hello(void)
{
printk(KERN_ALERT "Hello-world was terminated\n");
}

// The next two macros are mandatory, this way we declare
// our init and exit functions
module_init(start_hello);
module_exit(stop_hello);

// End of code


Some notes regarding printk:

printk is actually the “printf” of the kernel space (which we cannot use since the kernel ir running without the C libs), For each printk calling we can declare the output priority using the following defines in the kernel.h header:

#define KERN_EMERG      "<0>"   /* system is unusable                   */

#define KERN_ALERT "<1>" /* action must be taken immediately */
#define KERN_CRIT "<2>" /* critical conditions */
#define KERN_ERR "<3>" /* error conditions */
#define KERN_WARNING "<4>" /* warning conditions */
#define KERN_NOTICE "<5>" /* normal but significant condition */
#define KERN_INFO "<6>" /* informational */
#define KERN_DEBUG "<7>" /* debug-level messages */
In order to compile the above code, Here's the Makefile:

#Start of Makefile

# The sourc file to compile
obj-m += hello.o
# The kernel header files
KERNELDIR=/usr/src/kernels/2.6.25.9-76.fc9.i686
# Current directory
PWD= $(shell pwd)
# Make command
MAKE=make

all:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KERNELDIR) M=$(PWD) clean

# Since the make start by changing the current directory to the KERNELDIR
# path, The M option cause the makefile to move back to our directory before
# its trying to build out module.

#End of Makefile


Module installation:

Since the only thing our module is (currently) doing is to print its message, we will try to install it and capture its outputs, this can be done using the dmesg function or going directly to the /var/log/messages file (I'm usually running the “tail -f /var/log/messages” command on separate console) , now when we will install the module (go to the file location and type “insmod hello.ko”), We will see the following output :
Hello World strated :-]

and while removing the module (“rmmod hello”):
Hello-world was terminated