Linux下系统调用的组成与实现

主要包括三个部分:(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 ----->  给用户空间返回结果



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值