Sunday, October 18, 2009

Xen-tools and ubuntu Dom0

Installing Xen as described here does not install the xen-tools properly. Even if the hypervisor and Dom0 are up perfectly, there is nothing more that can be done without xen-tools.

$ sudo xm list

Traceback (most recent call last):
File "/usr/sbin/xm", line 5, in
from xen.xm import main
ImportError: No module named xen.xm

Thanks to Shriniket and Hormazd for reproducing the error :-)

As described here, the solution to this problem involves editing the
Config.mk file.

The Config.mk file is in the source root directory.

The following lines (line no. 38 and 39) have to be changed from :

PYTHON      ?= python
PYTHON_PREFIX_ARG ?= --prefix="$(PREFIX)"

to :

PYTHON = python
PYTHON_PREFIX_ARG =

Save the changes. Then,

# make clean

# make install-xen

# make install-tools

# make install-stubdom


Doing
# make clean and # make install-tools might be sufficient.
Haven't tried it.


Everything should be working fine now.

Tuning Config.mk results Xen packages to be placed
into /usr/local/lib/python2.6/dist-packages due to
Changeset 19594 in xen-3.4-testing.hg.
Otherwise, Xen packages would go to
/usr/lib/python2.6/site-packages,
which is not default location for python 2.6 on Ubuntu 9.04
( as opposed to Fedora 11 ).
Thus you won’t be able to start xend in Dom0.

Cheers !

Monday, October 5, 2009

Problems with getting Xen working ...

IF you are looking for how to install Xen, you can find it here.

Trying to get Xen working , ran into some problems ...

1. There is this peculiar problem that I faced with all the kernels that I tried as Dom0.

Gave up waiting for root device. Common problems:
-Boot args (cat /proc/cmdline)
-Check root delay = (did the system wait long enough?)
-Check root=(did the system wait for the right device?)
-Missing modules (cat /proc/modules; ls /dev)
ALERT! /dev/disk/by-uuid/xxxxx-xxxx-xxxxxxxxxxxx does not exist. Dropping to shell!

Busybox v1.10.2 (Ubuntu 1:1.10.2-2ubuntu7) built-in shell (ash)
Enter 'help' for a list of built-in commands.


The hypervisor was booting fine, but the Dom0 refused to recognise my root device and would drop me into busybox.

The solution to this problem is to pass an extra parameter to the kernel, indicating that it should wait longer for the root device. (SCSI disks have this problem).
So now, you need to edit your /boot/grub/menu.lst. The parameter to be passed is "rootdelay". rootdelay=90 has worked for me. You may experiment with lower/higer values.

$sudo gedit /boot/grub/menu.lst


#######Snippet - menu.lst ###########

title Xen 3.4.0 / Ubuntu 9.04, kernel 2.6.18.8
uuid fe8adb1a-7b82-40c4-b7d9-e35921c1155f
kernel /boot/xen-3.4.0.gz
module /boot/vmlinuz-2.6.26-2-xen-686 root=LABEL=root ro console=tty0 rootdelay=90
module /boot/initrd.img-2.6.26-2-xen-686



2. The second problem that I faced was with the 2.6.18 xenified kernel. The kernel boots into busybox and the keyboard becomes totally unusable. None of the keys works.
Although I did notice that the quickplay buttons do generate an interrupt ( it shows a message on the screen when I press a quickplay button), the rest of the keys are useless.

Could not fix this :-(

3. The 3rd problem that I faced was with the 2.6.26 Debian xenified kernel, along with the first one.

ata1.00: qc timeout (cmd 0xec)
ata1.00: failed to IDENTIFY (i/o error, err_mask= 0x4)


A little googling led me to think this was an ACPI problem. So I tried passing acpi=off in the kernel cmdline, but did not work out.
Some more googling led me in various directions. Tried atleast 5 different parameters.

The one parameter that finally worked was pci=nomsi . Found it here, and oddly enough as a solution to a different problem !

Apparently this is occurs due to problem of the Debian kernel on some motherboards and is consistently reproducable.

So, the final kernel command line that works perfectly is :

/boot/vmlinuz-2.6.26-2-xen-686 root=LABEL=root ro console=tty0 rootdelay=90 pci=nomsi


Hope this helps !

Cheers ! :-)

Sunday, October 4, 2009

Installing Xen 3.4.1

Recently, there was need to install Xen on my laptop for project work.

Xen 3.3 is present in the ubuntu repositories and installation is very straight forward.

If you plan to use Xen 3.3, then the task is extremly easy.

Steps :

1.Installing the Xen hypervisor.

sudo apt-get install ubuntu-xen-desktop

2. Installing a Dom0 kernel. There are various options available.
i) You can either use the 2.6.18.8 xenified kernel available on the official website. Get it here.
ii) You can download Debian xenified kernel from here and the modules for the kernel from here.
iii) You can use download a vanilla kernel from here and patch it to work as a Dom0. You can get the patches here. Patches for version 2.6.29-6 are stable.
iv) You can download a vanilla kernel and configure it as a Dom0 using PVOPS. (There are still quite a few issues with this.)

3. Done.

Installing Xen 3.4.1 :

Detailed steps :

I am describing how to install Xen 3.4.1 from source and using the Debian xenified kernel (2.6.26) as Dom0. I compiled the 2.6.18.8 xenified kernel, but my keyboard would become unusable. I also tried patching the vanilla kernel, but ran into some problems. So I settled for the Debian xenified kernel.

Step 1: Satisfying the dependencies.

Special thanks to Furquan Shaikh, my senior, for providing me a comprehensive list of all the dependencies.

$ sudo apt-get install gcc make binutils zlib1g-dev pyhton-dev python2.6-dev python-opnessl libncurses5-dev libssl-dev xorg-dev bridge-utils iproute udev tetex-base tetex-bin latex-make texi2html texinfo texlive texlive-base gawk gettext-kde


Alternatively, you can automate the process using :
$ sudo apt-get build-dep package-anme


For more info on this, click here and here
Thanks to CDK :-)

will install all the required dependencies.



Step 2 : Downloading the latest Xen source. You can download the source from here.

Step 3 : Extract the source into a suitable directory. Then
i) # make install-xen
ii) # make install-tools
iii)# make install-stubdom

If all the dependencies were satisfied, step 3 should not give any problems at all.

Step 4 : The packages for Dom0 Debian kernel can be obtained from here and here.

Once downloaded, install the kernel using :

$ sudo dpkg -i linux-image-2.6.26-2-xen-686_2.6.26-19_i386.deb linux-modules-2.6.26-2-xen-686_2.6.26-19_i386.deb

This installs the Dom0 kernel and also updates the grub entries.

This completes installation of the hypervisor and the Dom0. Since the Dom0 kernel is 2.6.26, make sure that your root partition is not ext4. ext4 support was included since kernel 2.6.28.

Now, reboot your computer, you should boot into the Dom0 kernel if everything went right. :-)

I ran into some problems while booting the Dom0 kernel. I am posting them here.

Saturday, August 15, 2009

Adding system calls to the Linux kernel

Adding new system calls to the Linux kernel

This article talks about adding new system calls to the Linux kernel on an x86 machine , version 2.6.XX

Disclaimer : This is by no means a complete and/or definitive guide. It is based purely on whatever little experience I have.

In this article , we will implement a linked-list in the kernel space which stores one integer value per node and write new system calls to add new items to the list, delete existing items and to display the contents of the list.

Adding new system calls to the kernel involves editing some kernel files, the files that have to be edited are :

So, first of all, download a kernel source from http://kernel.org and extract in into a suitable location.

(The pathnames are relative to the source base directory)

1. /arch/x86/kernel/syscall_table_32.S

2. /arch/x86/include/asm/unistd_32.h

3. /include/linux/syscalls.h

4. /Makefile

Next, we are going to put all the new files that we create into a separate directory.

Let's call that directory as "lister" . Note that this is not at all necessary, we can simply add our system calls in the kernel/sys.c file

So, in the source base directory, we will create a directory named "lister" which will hold all the new files that we create.

The new files that we will be creating are :

5. lister/lister.c

6. lister/lister.h

7. lister/Makefile

Finally, we'll create some user-space files to test the system calls. We'll see more about these files later.

Now, lets get started !!

1. The first file to be changed is the arch/x86/kernel/syscall_table_32.S file.

This file contains the names of all the system calls, prefixed with "sys_"

Since, we will be adding 3 new system calls to the kernel, which we will be naming as listadd, listdel and listshow, we will have to append 3 lines to this file as :

.long sys_listadd

.long sys_listdel

.long sys_listshow

2. Next, we'll modify the arch/x86/include/asm/unistd_32.h file.

This file contains an unique number associated with the system call that is passed to the kernel through the EAX register (specific to x86) when a system call is invoked.

Again, we will have to append 3 lines to the file as follows :

The general structure of the line is

" #define __NR_<system_call_name><last_system_call_number +1>"

so, after adding the relevant lines to the files,the file will look somewhat like this :

----------------------- snippet ----------------------------

#define __NR_preadv 333

#define __NR_pwritev 334

#define __NR_listadd 335 /* newly */

#define __NR_listdel 336 /* added */

#define __NR_listshow 337 /* lines */

#ifdef __KERNEL__

#define __ARCH_WANT_IPC_PARSE_VERSION

----------------------- snippet ----------------------------

3. Next, we will edit the file include/linux/syscalls.h that holds the declarations of all the system calls.

We will add the declarations of our 3 system calls to this file.

For the listadd system call ,

asmlinkage long sys_listadd(int __user *);

Now the above declaration says that the listadd system call takes 1 parameter, which is a pointer, in the user-space, to an integer.

Similarly, we add the declarations of the other two system calls.

asmlinkage long sys_listdel(int __user *);

asmlinkage long sys_listshow();

4. Next, we modify the /Makefile so that the files that we will be creating in our "lister" folder get complied.

Add lister/ to core-y (Search for regex: core-y ).The "lister" directory will contain the source file, header file and the Makefile for our system call.

So, the line would look something like this :

core-y := usr/ lister/

5. Now we create a directory in the source base directory, that will hold our files that contain the code of our system calls.

Let's call that directory as "lister"

Now, we will write the actual implementation of the system calls.

It consists of making 2 files, in our case, we call those files, lister.c and lister.h

6. Create a file called lister.h .

The contents of the header file can be something like this :

------------------ LISTER.H ------------------------------

#ifndef LISTER_H

#define LISTER_H

#include<linux/list.h>

struct linked_list{

struct list_head list;

int data;

};

struct list_head linked_list;

int no_of_elements = 0;

#endif

------------------- END ------------------------------------

This header file defines the node structure of our linked-list.

It also declares the head of the linked-list (named linked_list) and a variable that holds the number of elements in the list.

7. Now, we will write the actual system calls.

We create a file called lister.c  The indentations in the code are eaten up by Blogger...

----------------------------- LISTER.C -------------------------------

#include<linux/syscalls.h>

#include<linux/list.h>

#include<linux/slab.h>

#include<linux/kernel.h>

#include<asm/uaccess.h>

#include<linux/linkage.h>

#include "lister.h"

SYSCALL_DEFINE1(listadd,int __user*,buffer)

{

int data;

struct linked_list *new = (struct linked_list*) \

kmalloc(sizeof(struct linked_list),GFP_KERNEL);

if(no_of_elements == 0){

INIT_LIST_HEAD(&linked_list);

}

get_user(data,buffer);

new->data = data;

list_add_tail(&new->list,&linked_list);

no_of_elements++;

return 0;

}

SYSCALL_DEFINE1(listdel,int __user*,buffer)

{

int data;

struct list_head *ptr;

struct linked_list *entry;

get_user(data,buffer);

if(no_of_elements > 0){

list_for_each(ptr,&linked_list){

entry = list_entry(ptr,struct linked_list,list);

if(entry->data == data){

list_del(ptr);

return 0;

}

}

}

return -1;

}

SYSCALL_DEFINE0(listshow)

{

struct list_head *ptr;

struct linked_list *entry;

if(no_of_elements > 0){

list_for_each(ptr,&linked_list){

entry = list_entry(ptr,struct linked_list,list);

printk(KERN_ALERT "%d\n",entry->data);

}

}

}

---------------------------- END -------------------------------------

The SYSCALL_DEFINEx macro is defined in the syscalls.h file. It is, as the name suggests, used to define a system call.

Here, "x" is the number of parameters that the system call takes.

So the line :

SYSCALL_DEFINE1(listdel,int __user*,buffer)

says that : define a system call with the name "listdel", which takes 1 parameter and the parameter is a pointer, in user-space, to an integer.

The name of the pointer is the third argument.

so in general,

SYSCALL_DEFINE0(<name_of_system_call>)

SYSCALL_DEFINEx(<name_of_system_call>, <type_of_arg_1>, <name_of_arg_1>, ... , \ <type_of_arg_x>, <name_of_arg_x>)

The rest of the code is fairly straight-forward.

The get_user() macro copies the data from the user-space to the kernel-space.

The list_for_each() macro is used for iterating through the list.

The list_entry() macro returns a pointer to the linked-list node, given a pointer to the list_head struct within that node as the argument .

8. Now, we write a simple Makefile to compile our files

----------------------- Makefile -------------------------------------

obj-y += lister.o

----------------------- END -------------------------------------

This completes our kernel-space code.

Now, to test this code, we need to write some user-space code.

For this, we write 2 files, test.c and tester.h

9. Now, we will write wrapper functions for the system calls and put then together in a header file. Let's call that file as "tester.h"

Writing wrapper functions is not necessary, but it improves the readability of the code.

----------------------- TESTER.H ----------------------------

#include<linux/unistd.h>

#include<sys/syscall.h>

#define __NR_listadd 335

#define __NR_listdel 336

#define __NR_listshow 337

static long add_in_list(int * buff)

{

return syscall(__NR_listadd,buff);

}

static long del_from_list(int * buff)

{

return syscall(__NR_listdel,buff);

}

static long show_list(void)

{

return syscall(__NR_listshow);

}

------------------------- END --------------------------------

Note here that the numbers in the #define s have to be exactly the same as those in the unistd.h file

Here, in this header file, we wrote 3 wrapper functions for each of the system calls.

The _syscall() macro is the actual invocation of the system call.

Here, the arguments to the wrapper functions are simple integer pointers, instead of the int __user * that we used earlier. This is because this code is in the user-space, while the earlier code was in the kernel-space.

10. Now, we'll write a simple program to test the system calls. Let's call that file "test.c"

----------------------- TEST.C ----------------------------

#include<stdio.h>

#include "tester.h"

int main()

{

int data;

int i;

for(i=0;i<4;i++){

printf("\nEnter the number : ");

scanf("%d",&data);

add_in_list(&data);

show_list();

}

printf("\nDelete : ");

scanf("%d",&data);

del_from_list(&data);

}

---------------------- END ---------------------------------

The code is very simple, nothing really to explain.

Just compile and install the kernel so that system calls become available.

Then compile and execute "test.c" to test out the system calls.

Any kind of criticism is welcome ! :-)

Wednesday, August 12, 2009

Random

It's been quite a while since the last post. I've been kinda busy ( read LAZY) in the last 3 months.

A lot has happened since the last post was published. Okay, as you might have guessed, this is _not_ a technical post. :-)

College in the Final year has really been fun. It's been less about attending lectures and more about playing Table Tennis and Carom !!
We now have a week long off as a measure to control the swine flu epidemic in the city. I hate swine flu, but I like the holidays :-) :P

One of the best things that has happened since then is that now i have a job ! [:D]

Yeah, we had campus recruitment in our college and I was one of the lucky few to have been recruited to ThoughtWorks.
The recruitment process for ThoughtWorks was rather gruelling...spanning over 3 days and 6 rounds, 7 actually, if you count the aptitude/logic test that i had to give before being handed over the offer letter !
So, after a logic test, group activity round, coding round, 1st technical interview, 2nd technical interview, HR interview and a logic test to test my speed & accuracy...here I am !
But having survived so many rounds makes my selection feel all the more satisfying :-)

We also got our results in the last week. I've done pretty well this time around. For the first time, a girl didn't top the class :P

We also have to do an year long project in the final year. My project group ( 4 of us) have been working really hard in the last couple of months, reading lots research papers / blogs / TO-DO lists to find a good project idea. We're hoping to zero down on a good idea soon ( Its been like this for the last month :P ). Really looking forward to working with the group.

I wont say the customary "Look forward to more posts in the near future" stuff , coz i know that its not gonna happen. I'm not a regular blogger and I'm too lazy to become one :P

This post came purely out of the guilt of seeing most of my friends blog in the last couple of days :P
Special inspiration from Aruna, who has been blogging furiously in the last 15 days :-)

So, until the next post, Cya !
Take care. Be safe. Bunk college !
--Cheers !

Saturday, May 2, 2009

HP remote control in ubuntu ....how to get it working ....

Got a new laptop couple of months ago :D
HP Pavilion dv5 1104TU and it completely rocks ! :D

Well, it also came with a neat little remote control with lots of media buttons to make life easy. It worked perfectly under Vista, but refused to work with ubuntu (tried on 8.10 and 9.04). Now, I've finally come up with a way to get it working on Ubuntu.

Just follow this procedure and nothing can go wrong !

Firstly, you'll need to get lirc .
To install lirc, click here
Note : Select "none" and "none" when it asks for configuration during isntallation.

After that, download the configuration file for the Remote from here .This is the configuration file for the remote that comes with the DV6 series, but it works just fine with DV5 series too.

Now save this file as lircd.conf in /etc/lirc/

After this , edit the hardware.conf file to match this :

# /etc/lirc/hardware.conf
#
#Chosen Remote Control
REMOTE="None"
REMOTE_MODULES="lirc_dev lirc_serial"
REMOTE_DRIVER="default"
REMOTE_DEVICE=""
REMOTE_LIRCD_CONF=""
REMOTE_LIRCD_ARGS=""

#Chosen IR Transmitter
TRANSMITTER="None"
TRANSMITTER_MODULES=""
TRANSMITTER_DRIVER=""
TRANSMITTER_DEVICE=""
TRANSMITTER_LIRCD_CONF=""
TRANSMITTER_LIRCD_ARGS=""

#Enable lircd
START_LIRCD="true"

#Don't start lircmd even if there seems to be a good config file
#START_LIRCMD="false"

#Try to load appropriate kernel modules
LOAD_MODULES="true"

# Default configuration files for your hardware if any
LIRCMD_CONF=""

#Forcing noninteractive reconfiguration
#If lirc is to be reconfigured by an external application
#that doesn't have a debconf frontend available, the noninteractive
#frontend can be invoked and set to parse REMOTE and TRANSMITTER
#It will then populate all other variables without any user input
#If you would like to configure lirc via standard methods, be sure
#to leave this set to "false"
FORCE_NONINTERACTIVE_RECONFIGURATION="false"
START_LIRCMD=""


Save it

Go to the terminal and ..

 sudo /etc/init.d/lirc start 


and Voila ! if you have done everything correctly, the remote should be working now.
You can try it out from System->Preferences->Keyboard Shortcuts
Hope that helps ! :-)
Cheers !