使用者態調用Xen超級調用與Linux核心系統調用

來源:互聯網
上載者:User
一、從使用者態訪問系統調用通常,系統調用靠C庫支援。使用者程式通過包含標準標頭檔並和C庫連結,就可以使用系統調用。但如果你僅僅寫出系統調用,glibc庫恐怕並不提供支援。

這裡有一個好訊息還有一個壞訊息,好訊息是Linux本身提供了一組宏定義linux/include/asm-x86_64/unistd.h檔案中。壞訊息是在2.6.20之後的核心版本取消了這一系列的宏,導致一開始編譯源檔案的時候出錯,最後在2.6.18中找到了這段代碼。其實這段彙編主要的作用就是將系統調用號傳遞給EAX寄存器,同時將從EAX寄存器取出傳回值。

//test.c#include <stdio.h>#include <syscall.h>#include <linux/errno.h>#include <errno.h>#define __NR_foo 312#define MAX_ERRNO 127#define __syscall "syscall"#define __syscall_clobber "r11","rcx","memory"#define __syscall_return(type,res)\    do{\        if((unsigned long)(res) >= (unsigned long)(-MAX_ERRNO)){\            errno = -res;\            res = -1;\        }\        return (type)(res);\    }while(0)#define _syscall0(type,name)\    type name(void){\        long __res;\        __asm__ volatile(__syscall\                : "=a" (__res)\                : "0" (__NR_##name) : __syscall_clobber );\        __syscall_return(type,__res);\    }_syscall0(long,foo)int main(int argc,char** argv){    long stack_size = 0;    stack_size = foo();    if(stack_size == -1)    perror("ERROR");    printf("The kernel stack size is %ld\n",stack_size);    return 0;}Output: The kernel stack size is 8192

這裡面有幾點需要注意。

(1)由於我所編譯的環境的核心版本是3.2.6,而之前也已經介紹過在2.6.20之後unistd.h檔案中不再存在有這些宏,因此宏需要自己聲明。上面的宏聲明是我從2.6.18核心中拷貝過來的。

(2)除此之外還會遇到一個宏__syscall_return(type,res)用於返回系統調用執行後的傳回值。

(3)在_syscallX這一系列宏當中存在一個__syscall宏,在源檔案的開始定義為“syscall”,曾經試圖去找它的定義,但是沒有發現。需要說明的是,在我最初用“int $0x80”而不是“syscall”的時候,系統調用不成功。ERROR返回錯誤:Dad Address。

(4)在聲明_syscall0(long,foo)後面沒有分號。

下面的例子是從網上發現的。可以看到通過函數syscall將系統調用號傳遞進去。這樣調用系統調用更方便。

//test1.c#include <stdio.h>#include <asm/unistd_64.h>#include <syscall.h>#include <sys/syscall.h>#define __NR_foo 312int main(int argc,char** argv){    long ret = 0;    ret = syscall(__NR_foo);    printf("Thread Stack Size is %ld\n",ret);    return 0;}Output: Thread Stack Size is 8192

二、從使用者態訪問超級調用以下是在網上發現的一個使用者態調用Xen中hypervisor的例子。該例子中類似上面系統調用在Xen中新添加了一個超級調用。

#include <stdio.h>#include <errno.h>#include <stdlib.h>#include <sys/ioctl.h>#include <sys/types.h>#include <fcntl.h>#include <string.h>#include <xenctrl.h>#include <xen/sys/privcmd.h>#define __HYPERVISOR_print_string 39int main(int argc,char** argv){    int fd = 0;    int ret = 0;    char* message = NULL;    if(argc != 2)    {        printf("Please input one parameter!\n");        return -1;    }    message = (char*)malloc(sizeof(char) * strlen(argv[1] + 1));    if (message == NULL) {        printf("malloc failed");        return -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);    perror("ioctl err");    printf("ret = %d\n",ret);        close(fd);    return 0;}

之後便以Xen,重新載入Xen hypervisor,在xm dmesg命令下即可查看hypercall運行結果。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.