Linux内核systemcall调用“int 0x80”

时间:2012-10-09 09:05:43

标签: c linux assembly linux-kernel system-calls

我正在研究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

2 个答案:

答案 0 :(得分:5)

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

我也在eglibc中找到了syscall源代码,它看起来确实不同: http://www.eglibc.org/cgi-bin/viewvc.cgi/trunk/libc/sysdeps/unix/sysv/linux/x86_64/syscall.S?view=markup

所以看起来int $0x80对x86_64 Linux内核不起作用,你需要使用syscall

答案 1 :(得分:2)

我有两个主意。

  1. 您是否更新了系统调用表?

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

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

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