问题
I am studying the Linux kernel and at the moment I try to implement my own system call.
In the kernel code it looks the following:
asmlinkage long sys_my_syscall()
{
printk("My system call\n");
return 0;
}
If I call it with a systemcall()
function it works fine, but I have found another one way:
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);
}
But it returns the value -14
EFAULT
.
What am I doing wrong?
Setup: Linux kernel 3.4, ARCH x86_64
回答1:
For 64-bit systems the Linux system call ABI is completely different from i*86 one unless there's a layer of compatibility. This may help: http://callumscode.com/blog/3
I also found the syscall source in the eglibc, it looks different indeed: http://www.eglibc.org/cgi-bin/viewvc.cgi/trunk/libc/sysdeps/unix/sysv/linux/x86_64/syscall.S?view=markup
So it looks like int $0x80
does not work for x86_64 Linux kernels, you need to use syscall
instead.
回答2:
I have two ideas.
- Did you update the system call table?
For kernel 4.14, it's arch/x86/entry/syscalls/syscall_64.tbl
- Did you enbale the COMPAT_32 kernel option?
If not, int 0x80 won't work. It seems your system had enabled this option, or you would hit the #GP exception.
来源:https://stackoverflow.com/questions/12796458/linux-kernel-systemcall-call-with-an-int-0x80