超级调用实现原理

来源:互联网 发布:淘宝群优惠群怎么做的 编辑:程序博客网 时间:2024/06/05 11:31

1.为什么要超级调用?

    在Xen虚拟机系统中,对于特权操作,虚拟机操作系统通过软中断TrapXen VMM中,通过超级调用来实现某些特权指令和敏感指令。超级调用就类似于操作系统的系统调用,只是系统调用在操纵系统中实现,而超级调用在虚拟机管理器VMM中实现,是更底层的实现。所以叫超级调用。

2.有哪些超级调用的形式?

    超级调用使用0x82的中断号,参数通过寄存器传递。超级调用不仅面向1还的虚拟机内核,还面向3环的应用程序。

对于1环:GuestOS内核无法执行某些特权操作,XEN通过超级调用(hypercall)向GuestOS提供执行的调用接口。



三环:通过特殊的内核驱动Primcmd ,应用程序通过系统调用ioctl进入1Guest OS内核使用超级调用。



所以,也就是说对于3环的超级调用可,需要由3环先通过系统调用进入1环,然后再进入超级调用的过程。

3.超级调用的实现

比如我们要在xen中添加一个打印消息的hypercall,参数有一个,类型为char*, 代表我们要打印的消息. 函数原型为:do_print_string(char* message)



  在这个{}里面添加HYPERCALL(do_print_message)






操作如下:

[root@localhost f302]# vim call_test.c 

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<fcntl.h>
#include<xenctrl.h>
#include<sys/ioctl.h>
#include<sys/types.h>
#include<xen/sys/privcmd.h>
int main()
{
        int fd,ret;
        char message[]="hello";
        privcmd_hypercall_t hcall={
                __HYPERVISOR_print_string,
                {message,0,0,0,0}
        };
        fd=open("/proc/xen/privcmd",O_RDWR);
        if(fd<0){printf("open fd error!\n");exit(1);}
        else printf("fd=%d\n",fd);


        ret=ioctl(fd,IOCTL_PRIVCMD_HYPERCALL,&hcall);
        printf("ret=%d\n",ret);
}
[root@localhost f302]# gcc call_test.c 
call_test.c: In function ?.ain?.
call_test.c:15: warning: initialization makes integer from pointer without a cast

[root@localhost f302]# ./a.out 
fd=3
ret=1

(XEN) The message is:hello
(XEN) The message is:hello

上传几张实际操作的图片看看:

1.给虚拟机配置网络


2.在半虚拟化的Guest中,超级调用成功


ret=1,超级调用成功!

3.在全虚拟化的虚拟机中,超级调用失败


ret=-1,表示调用失败。

4.超级调用的应用

  超级调用和事件通道总是一起使用的,比如事件通道总是通过超级调用来操作(包括11种)的。