Adding a new system call to a Linux system typically requires three steps:
1. Register the new system call number
2. Update system Call Table
3. Add a new function
Adding a hypercall to Xen is similar to adding a system tuning to Linux. is basically a few steps above.
Now give a concrete example:
For example, we want to add a print message in Xen Hypercall, the parameter has one, the type is char*, on behalf of the message we want to print. The function prototype is:
Do_print_string (char* message), Xen has 37 hypercall in Central, so we add the super call number 38.
1. Register a Hypercall call number first.
Xen/include/public/xen.h
#define __HYPERVISOR_KEXEC_OP 37
+ #define __hypervisor_print_string 38
2. Update system Call Table
/xen/arch/x86/x86_32/entry. S
ENTRY (hypercall_table)
. Long Do_kexec_op
+. Long do_print_string
ENTRY (hypercall_args_table)
. Byte 2/* DO_KEXEC_OP * *
+. Byte 1/* do_print_string * *
3. Define function Header File
/xen/include/asm-x86/hypercall.h
extern int
Do_kexec (
unsigned long op, unsigned arg1, xen_guest_handle (void) uarg);
+extern int
+do_print_string (char * message);
4. Define function (function definition in appropriate file, this example uses MM.C)
/xen/arch/x86/mm.c
int do_print_string (char * message)
{
if (message)
PRINTK ("The message Being:/n%s/n", message);
else PRINTK ("no message!/n");
return 1;
}
Ok.
Recompile installation
Make Dist
Make install
Re-make img
Mkinitrd-v-F initrd-2.6.18.8-xen.img 2.6.18.8-xen
Reboot
Then edit a. c file and test the new hypercall in user space. as follows:
(Xen provides privcmd this driver file so that IOCTL can be invoked in the 3 loop (user space) to invoke Hypercall)
View Plaincopy to Clipboardprint?
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>
#include <xenctrl.h>
#include <xen/sys/privcmd.h>
int main (int argc, char *argv[])
{
int FD, RET;
char * message;
if (argc!= 2) {
printf ("Please put one parameter!/n");
return-1;
}
Message = (char *) malloc (sizeof (char) * (strlen (argv[1)) +1);
strcpy (message, argv[1]);
privcmd_hypercall_t Hcall = {
__hypervisor_print_string,
{message, 0, 0, 0, 0}
};
FD = open ("/proc/xen/privcmd", O_RDWR);
if (FD < 0) {
Perror ("open");
Exit (1);
} else
printf ("FD =%d/n", FD);
RET = IOCTL (FD, Ioctl_privcmd_hypercall, &hcall);
printf ("ret =%d/n", ret);
}
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>
#include <xenctrl.h>
#include <xen/sys/privcmd.h>
int main (int argc, char *argv[])
{
int FD, RET;
char * message;
if (argc!= 2) {
printf ("Please put one parameter!/n");
return-1;
}
Message = (char *) malloc (sizeof (char) * (strlen (argv[1)) +1);
strcpy (message, argv[1]);
privcmd_hypercall_t Hcall = {
__hypervisor_print_string,
{message, 0, 0, 0, 0}
};
FD = open ("/proc/xen/privcmd", O_RDWR);
if (FD < 0) {
Perror ("open");
Exit (1);
} else
printf ("FD =%d/n", FD);
RET = IOCTL (FD, Ioctl_privcmd_hypercall, &hcall);
printf ("ret =%d/n", ret);
}
It can also be tested by invoking hypercall between kernel spaces in the form of loading modules.
Compile the file and test the following:
Check the log file to see if the new Hypercall installation was successful: (under Linux the log is generally/var/log/mesages, and Xen logs are viewed with XM DM commands)
Ok!
This article from Csdn Blog, reproduced please indicate the source: http://blog.csdn.net/sploving/archive/2009/10/10/4651260.aspx