Linux系统调用过程学习笔记

本文详细介绍了Linux系统调用的工作原理,包括初始化过程、系统调用号与表的定义、宏命令的使用以及软中断INT80H的具体实现。通过一个具体的open函数调用实例,清晰地展示了从用户空间到内核空间的整个调用流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Linux系统调用初始化:

在start_kernel()中调用trap_init(),设置中断向量表。


#define SYSCALL_VECTOR    0x80

set_system_gate (SYSCALL_VECTOR, &system_call) ;     //当系统遇到INT80H中断时,即CPU跳转到相应中断服务程序,&system_call为中断服务程序入口地址


系统调用号如下

#define  __NR_exit      1

#define  __NR_fork      2

......

#define  __NR_open    5

......

#define  __NR_socketcall   102

......

系统表用表如下

.data

ENTRY (sys_call_table)

.long  SYMBOL_NAME(sys_ni_syscall)         //0

.long  SYMBOL_NAME(sys_exit)                     //1

.long  SYMBOL_NAME(sys_fork)                     //2

.......

.long SYMBOL_NAME(sys_open)                   //5

......

.long SYMBOL_NAME(sys_socketcall)          //102

......


宏命令展开函数,一共6个,用于系统调用格式转换和参数传递

#define _syscall1(type, name, type1, arg1)\

type name(type arg1)\

{\

    long __res;\

    __asm_volatile("int $0x80"\

     : "=a" (__res) \

    : "0" (__NR_# #name), "b" ((long)(arg1)));\

    __syscall_return(type, __res);\

}

#define _syscall2(type, name, type1, arg1, type2,arg2)\

......

#define _syscall6(type, name, type1, arg1, type2, arg2, type3,arg3, type4, arg4, type5, arg5, type6, arg6)


软中断INT80H代码

ENTRY(system_call)

        pushl %eax 

        SAVE_ALL       # 这两句为保存现场  

        GET_CURRENT(%ebx)    #得到进程的ask_struct

        testb $ 0x02, tsk_ptrace(%ebx) # PT_TRACESYS

        jne  tracesys

       cmpl $(NR_syscalls), %eax

       jae badsys

       call  *SYMBOL_NAME(sys_call_table)( , % eax, 4)

       movl %eax, EAX(%esp)

ENTRY(ret_from_sys_call)

...    

ENTRY(ret_from_sys_call)

       cli

       cmpl $ 0,need_resched( %ebx)

       jne reschedule

       cmpl $0, sigpending( %ebx)

       jne signal_return      //有无信号量

       restore_all:

       RESTORE_ALL //恢复现场

ALIGEN

       signal_return:

....

#define RESTORE_ALL

       popl ......

       ......

       iret;

                       

系统调用过程:用户进程下执行系统调用命令->转换为_syscallN()展开的函数->执行INT80H软中断->查找系统调用表->找到执行对应内核函数->进入内核模式执行相关操作->ret_from_sys_call结束调用->恢复现场,回到用户进程


举例说明:

1.  int  open (char* filename, int flag, int mode)

2.  转换为_syscall3()展开的函数为 _syscall3(int, __NR_open, const char*, file, int, flag, int, mode) ,__NR_open变成系统调用号5,存入EAX,file、flag、mode依次存入EBX、ECX,EDX

3.  执行INT80H软中断,保护现场, call  *SYMBOL_NAME(sys_call_table) (,  %eax, 4)

4.  根据系统调用号5在系统调用表上找到对应内核函数 asmlinkage long sys_open (const char* file name, int flag, int mode)

5.  CPU进入内核态,执行相关open操作

6.  ret_from_sys_call返回到用户模式


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值