3

我正在研究 Linux 内核,目前我尝试实现自己的系统调用。

在内核代码中,它看起来如下:

asmlinkage long sys_my_syscall()
{
     printk("My system call\n");
     return 0;
}

如果我用一个systemcall()函数调用它,它工作正常,但我找到了另一种方法:

int my_syscall(void)
{
    long __res;
    __asm__ volatile (
    "movl $312, %%eax;"
    "int $0x80;"
    "movl %%eax, %0;"
    : "=m" (__res)
    :
    : "%eax"
    );
    if ((unsigned long) (__res) >= (unsigned long) (-125)) {
       errno = -(__res);
       __res = -1;
    }
    return (int)(__res);
}

但它返回值-14 EFAULT

我究竟做错了什么?

设置: Linux 内核 3.4,ARCH x86_64

4

2 回答 2

5

对于 64 位系统,Linux 系统调用 ABI 与 i*86 完全不同,除非有一层兼容性。这可能会有所帮助: http ://callumscode.com/blog/3

我还在 eglibc 中找到了系统调用源,它看起来确实不同: http ://www.eglibc.org/cgi-bin/viewvc.cgi/trunk/libc/sysdeps/unix/sysv/linux/x86_64/syscall.S ?view=标记

所以它看起来int $0x80不适用于 x86_64 Linux 内核,您需要syscall改用。

于 2012-10-09T10:19:58.760 回答
2

我有两个想法。

  1. 你更新系统调用表了吗?

对于内核 4.14,它是 arch/x86/entry/syscalls/syscall_64.tbl

  1. 您是否启用了 COMPAT_32 内核选项?

如果没有, int 0x80 将不起作用。您的系统似乎已启用此选项,否则您会遇到#GP 异常。

于 2018-09-17T07:21:50.803 回答