操作系统-系统调用

2021/9/18 23:35:08

本文主要是介绍操作系统-系统调用,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

系统调用概述

系统调用:运行在用户空间的程序向操作系统内核请求需要更高权限运行的服务。系统调用提供用户程序与操作系统之间的接口。

image-20210918222700665 image-20210916153416685

系统调用需要了解的点:

  • 系统调用将处理器从用户态切换到核心态,以便 CPU 访问受到保护的内核内存。

  • 每个系统调用都由一个唯一的数字来标识。

  • 系统调用可以有一套参数,用于用户空间与内核空间之间相互传递信息。(x86-64中最多使用寄存器传递6个参数,参考资料如下:

    x86-32 [Free|Open|Net|DragonFly]BSD UNIX System Call convention:

    Parameters are passed on the stack. Push the parameters (last parameter pushed first) on to the stack. Then push an additional 32-bit of dummy data (Its not actually dummy data. refer to following link for more info) and then give a system call instruction int $0x80

    x86-64 Linux System Call convention:

    1. User-level applications use as integer registers for passing the sequence %rdi, %rsi, %rdx, %rcx, %r8 and %r9. The kernel interface uses %rdi, %rsi, %rdx, %r10, %r8 and %r9.
    2. A system-call is done via the syscall instruction. This clobbers %rcx and %r11 as well as the %rax return value, but other registers are preserved.
    3. The number of the syscall has to be passed in register %rax.
    4. System-calls are limited to six arguments, no argument is passed directly on the stack.
    5. Returning from the syscall, register %rax contains the result of the system-call. A value in the range between -4095 and -1 indicates an error, it is -errno.
    6. Only values of class INTEGER or class MEMORY are passed to the kernel.

系统调用的详细过程

以x86-32为例,说明系统调用过程:

  1. 通过调用外壳(wrapper)函数发起系统调用(glibc)。

  2. 参数通过堆栈传入外壳函数,外壳函数会将上述参数复制到寄存器(系统调用最多使用6个)。

  3. 外壳函数将系统调用编号复制到eax寄存器中。

  4. 外壳函数执行中断机器指令(int 0x80),引发处理器从用户态切换到核心态,并执行系统中断0x80(十进制数128)的中断向量所指向的代码。

  5. 为响应中断0x80,内核会调用system_call()例程(位于汇编文件arch/i386/entry.S中)来处理中断,具体如下:

    5.1 在内核栈中保存寄存器值。

    5.2 审核系统调用编号是否有效。

    5.3 如果调用号有效,就去存放所有调用服务例程的列表中进行索引,发现并调用相应的系统调用服务例程。

    5.4 从内核栈中恢复各寄存器值,并将系统调用返回值置于栈中。

    5.5 返回至外壳函数,同时将处理器切换回用户态。

  6. 若系统调用服务例程的返回值表明调用有误,外壳函数会使用该值来设置全局变量 errno。然后,外壳函数会返回到调用程序,并同时返回一个整型值,以表明系统调用是否成功。

image-20210918223613321

其他

Linux常见的系统调用

image-20210918230718797

跟踪系统调用

Linux可以在命令行中使用 strace追踪系统调用 ,ltrace追踪库函数的调用。

Mac OS可以使用dtruss追踪系统调用。

reference

[1] UNIX 系统编程手册

[2] 现代操作系统



这篇关于操作系统-系统调用的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程