主要包括三个部分:(1)唯一的系统调用号(System Call Number);(2)系统调用表中相应的表项,即具体的函数地址;(3)对应的具体函数,即系统调用函数体。
以getpid()POSIX接口举例如下:
(1)系统调用号在文件 include/asm-x86/unistd_32.h中,表现如下:
/*
* This file contains the system call numbers.
*/
#define __NR_restart_syscall 0
#define __NR_exit 1
#define __NR_fork 2
#define __NR_read 3
#define __NR_write 4
#define __NR_open 5
#define __NR_close 6
#define __NR_waitpid 7
#define __NR_creat 8
#define __NR_link 9
#define __NR_unlink 10
#define __NR_execve 11
#define __NR_chdir 12
#define __NR_time 13
#define __NR_mknod 14
#define __NR_chmod 15
#define __NR_lchown 16
#define __NR_break 17
#define __NR_oldstat 18
#define __NR_lseek 19
#define __NR_getpid 20
#define __NR_mount 21
……
(2)系统调用表在系统中的位置是: arch/avr32/kernel/syscall_table.S
表现如下:
……
sys_call_table:
.long sys_restart_syscall
.long sys_exit
.long __sys_fork
.long sys_read
.long sys_write
.long sys_open /* 5 */
.long sys_close
.long sys_umask
.long sys_creat
.long sys_link
.long sys_unlink /* 10 */
.long __sys_execve
.long sys_chdir
.long sys_time
.long sys_mknod
.long sys_chmod /* 15 */
.long sys_chown
.long sys_lchown
.long sys_lseek
.long sys_llseek
.long sys_getpid /* 20 */
.long sys_mount
.long sys_umount
……
(3)具体的函数实现代码在系统中的位置是:kernel/timer.c
/**
* sys_getpid - return the thread group id of the current process
*
* Note, despite the name, this returns the tgid not the pid. The tgid and
* the pid are identical unless CLONE_THREAD was specified on clone() in
* which case the tgid is the same in all threads of the same group.
*
* This is SMP safe as current->tgid does not change.
*/
asmlinkage long sys_getpid(void)
{
return task_tgid_vnr(current);
}
那么,我们在系统中如何使用这个函数呢流程如下:
getpid(void) -------> int 0x80进入内核(同时从寄存器eax获取超级调用号) ---------> system_call , call *sys_ call_table(,%eax, 4)(这里的动作是将PC值改为%eax * 4 + sys_call_table) -----> sys_getpid(void) -------> system_exit , resume_userspace -----> 给用户空间返回结果