Xen & Linux KernelProgramming
Adding a System CallIonut Constandache
What is Xen? A virtual machine monitor (VMM) for x86
compatible computers Run multiple instances of OSes simultaneously
These are called Guest OSes Provides isolation between Guest OSes
Uses Paravirtualization Does not hide virtualization from the Guest OSes OS must be ported to work with Xen
Xen system structure Xen is lowest, most privileged system level Xen hosts multiple Guest OSes (called
domains in Xen) running in secure VMs Domain 0 – special privileged management
domain Builds other domains and manages their virtual
devices The domain you are logging in to when you ssh to
cps210.cod.cs.duke.edu
Using Xen in CPS 110 Xen machine: cps210.cod.cs.duke.edu Each team/student has an account on cps210 ssh into cps210.cod.cs.duke.edu
ssh [email protected] /usr/research/proj/cps110
Source files for linux kernel 2.6.16.29 linux2.6.16.29xenU.tar > copy it to your home directory The configuration file for running a DomU virtual machine TeamName.xen > copy it to your home directory tar xvf linux2.6.16.29xenU.tar > extract source files
The xm utility Command line utility to control guests
To start a machine: (sudo) /usr/sbin/xm create c teamname.xen the machine will start > you can login into it with root
(no password) exit from the machine ctrl5 (control returns to Dom0)
To list the machines currently running (sudo) xm list
To destroy a DomU guest machine (sudo) xm destroy machineID (from xm list)
Adding a system call Objectives:
Keep track of how many times each of the fork, vfork, execve and clone system calls is invoked
Place counters in kernel code
Implement a new system call providing this information
Request/retrieve these values from user space by invoking the new system call/s
System call recap'
The system call number is pushed into a register Trap instruction/software interrupt to switch from user
mode to kernel mode Kernel takes the system call number, indexes into the
table of system calls, and executes the system call handler
(eax) (syscall_table) (object code) __NR_syscall > syscallname > syscallname code
Adding a system call (1) Defining the syscall_No Edit include/asmi386/unistd.hcontents:#define __NR_restart_syscall 0
#define __NR_exit 1
#define __NR_fork 2
#define __NR_read 3
#define __NR_unshare 310
#define __NR_mysyscall 311 < add the next syscall_NO
#define NR_syscalls 312 < modify the number of available system calls
Adding a system call (2) Add the system call to the syscall_table Edit arch/i386/kernel/syscall_table.Scontents:.long sys_restart_syscall
.long sys_exit
.long sys_fork
.long sys_read
........................
.long sys_unshare /* 310 */
.long sys_mysyscall < add an entry to the last line (this is going to be the new system call)
Adding a system call (3)
Add the system call to syscalls prototype header file
Edit include/linux/syscalls.h
contents:
................
asmlinkage long sys_mysyscall(unsigned int cmd); < add the system call at the end of the file
#endif
Adding a system call (3) You can place the system call in a file that gets linked
into the kernel
Cleaner define your own file and modify the kernel Makefile to include the object code of your definition
Create a directory mysyscall in the kernel source file root directory (linux2.6.16.29xenU)
Adding a system call (4) In the directory mysyscall
Create a file mysyscall.c Create a file Makefile
Edit mysyscall.c#include <linux/kernel.h>
asmlinkage long sys_mysyscall(unsigned int cmd)
{
printk(KERN_DEBUG "cmd = %d\n",cmd);
return 0;
} Edit Makefileobjy := mysyscall.o
Adding a system call (5) Edit the Makefile in Linux source file root directory
Run make in Linux source file root direct
Look for corey += Add mysyscall/
corey += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ mysyscall/
Run make in Linux source file root directory In mysyscall/ > an object file mysyscall.o
Linux image is in vmlinuz
Run the VM
Edit TeamName.xen file Replace
kernel = "/usr/research/proj/cps110/vmlinuzxenU"
with the path to your new kernel image
(kernel = "/usr/research/home/Team/linux2.6.16.29xenU/vmlinuz")
Run the virtual machine with the new kernel
(sudo) xm create c teamname.xen
Invoke the system call In your VM create a file test.c
#include <sys/syscall.h>#include <stdio.h>#define __NR_mysyscall 311int main(){syscall(__NR_mysyscall,1);return 0;}
Compile it!
Run dmesg (displays kernel messages)
You should see the output printed by your system call
Tips The fork, vfork, execve and clone system calls are
implemented in arch/i386/kernel/process(xen).c
Your counters should be placed in this file
In order to get the counters in mysyscal.c you have to make them accessible (e.g define them extern in kernel.h)
Tips II Kernel 2.6 is preemptive you should protect the counters
with locks (use spinlocks)
spinlock_t > Ch 15 in Linux Device Drivers 3rd Ed.
If you need to allocate memory the kernel function is kmalloc
char* ptr = kmalloc(10*sizeof(char), GFP_KERNEL)
kfree(ptr);
Ch 8 in Linux Device Driver 3rd Ed.
Tips III User Space/Kernel Space memory – move system calls arguments to
and from user space Sanity checks: (#include <asm/uaccess.h>)
int access_ok(type, ptr, size); (return 1 if OK)type VERIFY_READ/VERIFY_WRITEsize in bytesptr > pointer to user space memory
Copying data get_user, put_user (for simple data types)
Ex: put_user(char, char*) (check return value == 0 ok!) copy_from_user, copy_to_user
Ex: copy_from_user(char *to, char __user *from, unsigned long size)
Tips IV Error codes:
Convention: if a function returns 0 > success any other value failure
You should write code using this convention Errors that kernel functions/system call should return are
defined errno.h (#include <asm/errno.h>) Always return ERRORCODE (e.g. EINVAL, EFAULT)
References
Linux Device Drivers 3rd Edition
http://lwn.net/Kernel/LDD3/
Linux Kernel Source Tree navigation
http://www.gelato.unsw.edu.au/lxr/source/?v=2.6.16