关于Linux的系统调用

【这里只研究 x86 平台下的】
1. 相关文件:
系统调用号的定义:
arch/x86/include/asm/unistd_32.h

这里对每个系统调用都分配了一个系统调用号。

系统调用表的定义:
arch/x86/kernel/syscall_table_32.S

这里是用汇编语言定义的系统调用表,系统启动时会加载到指定的内存区域

那么,这些sys_* 系统调用例程怎么定义的呢? 在某个版本以前,我们可以直接通过sys_* 找到该函数的定义,但是,在linux-3.1.1中,我们只能看到使用该函数的地方,却找不到定义该函数的地方了,因为可能通过宏来定义了,如: SYSCALL_DEFINE0, SYSCALL_DEFINE1,SYSCALL_DEFINE2,…
参考文件 include/linux/syscalls.h:

当然,也可能没有通过宏来定义,我们不妨还按照sys_ 来搜索。

让我们来找找sys_fork 吧:
grep SYSCALL_DEFINE -r * | grep fork
没有结果, 在试试sys_fork
grep sys_fork -r *
结果太多了,我只关心x86平台下的实现,如下:
grep sys_fork -r * | grep x86
大概在文件:./arch/x86/kernel/process.casm/syscalls.h 中

再看看./arch/x86/kernel/process.c :

我们知道,系统调用也是通过一个系统中断来实现的,linux上,所有的系统调用都是通过一个中断号为 0x80的中断来实现的,参考文件:
arch/x86/include/asm/irq_vectors.h

那么,中断向量表又是在什么时候初始化的呢?
arch/x86/kernel/traps.c 中初始化了中断向量表,里面也指定了 0x80 的中断处理例程是 system_call

那么, system_call 又是怎么定义的呢?
arch/x86/kernel/entry_32.S

这里我们还发现系统调用被跟踪的逻辑,就是 syscall_trace_entry, 同样出现在文件: arch/x86/kernel/entry_32.S中;
ptrace 函数就是利用这个功能来实现的。

那么, syscall_trace_enter 的实现又是在哪里的呢?
arch/x86/kernel/ptrace.c

ptrace是不是很强大? 记住: ptrace本身可不是系统调用,如果是的话就死循环了。

问题: ptrace.c 中没有定义ptrace这个函数,但是 man ptrace 时,却又如下定义:
long ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data);

那么这个函数又是怎么来的呢?

====================================================================

现在,我要执行一个fork系统调用时,是怎么通过fork符号来找到系统调用表中的指定的例程的呢???????????????

下面的就不要看了,只是猜测。。。。。。。。。。。。。。。。。。

系统调用都到这里来执行:
arch/x86/kernel/sys_i386_32.c

对于较新的cpu来讲,系统调用是通过: ./vdso/vdso32/sysenter.S 中的__kernel_vsyscall来实现的,其中使用了一个新的cpu指令: sysenter

留下评论

邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据