1. The system call vector numbers are defined in arch/arm/include/asm/unistd.h
#define __NR_restart_syscall(__NR_SYSCALL_BASE+ 0)
#define __NR_exit (__NR_SYSCALL_BASE+ 1)
#define __NR_fork (__NR_SYSCALL_BASE+ 2)
#define __NR_read (__NR_SYSCALL_BASE+ 3)
...
2. Inarch/arm/kernel/entry-common.S, defined a variable, sys_call_table, then put syscall handlers' address (which defined inarch/arm/kernel/calls.S) here:
.type sys_call_table, #object
ENTRY(sys_call_table)
#include "calls.S"
...
/* Special system call wrappers*/
...
sys_mmap2:
#if PAGE_SHIFT > 12
...
#else
str r5, [sp, #4]
b do_mmap2
#endif
ENDPROC(sys_mmap2)
Be noted:
A. each entry of the sys_call_table is the syscall handler's address.
B. Some system call handler (the wrappers) are defined in this file.
3. Most of the syscall routines are declared ininclude/linux/syscalls.h and defined in separate modules. For several special syscalls, for example, sys_mmap2(), system defines wrappers for them just below the sys_call_table. See above. That is, the system call, mmap2's handler is just defined in this assembly source file, and it calls do_mmap2().
3. Also the swi software interrupt handler is defined inarch/arm/kernel/entry-common.S. It's a quite long routine but basically, it does following:
ENTRY(vector_swi)
Get syscall number
...
enable_irq
...
ldrcc pc, [tbl, scno, lsl #2]@ call sys_* routine
ENDPROC(vector_swi)