System call

from Wikipedia, the free encyclopedia

A system call , also system call (from English system call ) or syscall for short , is a method used by application programs in computer technology to carry out functionalities provided by the operating system, such as reading a file. Control is passed from the program to the kernel .

Details

In modern computer systems (e.g. the IA-32 architecture from Intel ) the kernel , i.e. the operating system kernel , runs in the so-called privileged ring 0 (also called kernel mode ) and thus has access to the entire instruction set of the CPU and the entire memory area. For security reasons, on the other hand, normal user processes run in the unprivileged rings 1 to 3 (user mode) , in which fewer commands are available to them and therefore they cannot perform certain tasks directly. Does a process running in user mode have to perform a task that is only possible in a higher privileged ring, such as B. access to the hard drive or other hardware, he can inform the kernel by a system call and thus initiate a context change. The process transfers control of the CPU to the kernel and is interrupted until the request has been completely processed. After the system call, the kernel returns the CPU to the process in user mode and continues the program code at the point at which the context change was previously requested. At no time does the process leave its unprivileged ring and therefore cannot run the risk of endangering other processes or even the stability of the system kernel itself, since only trustworthy code from the kernel is executed in privileged mode.

A system call can be responsible for sending information to the hardware, the kernel itself or other processes, as well as reading such information. For this it is sometimes necessary to copy data from the private memory area of ​​the kernel, to which a normal process does not have access, into the address area of ​​a process, so that the process still has access to the data after the call and with the results of its query can do anything at all. This is also a result of the strict separation between kernel mode and user mode.

All POSIX -compatible operating systems must implement certain calls to ensure a certain portability between the systems. Many manufacturers also add their own extensions to the standard in order to open up additional options for the programmer. In the current Linux kernel 4.4 ( LTS ) for the x86 architecture , 376 calls are currently defined. The number of system calls in Microsoft Windows Vista is 360 according to unofficial sources.

Library functions

Most systems provide a programming interface (API) for system calls in the form of library functions that make it easier for a programmer to do work that requires extended access to the CPU's instruction set.

Frequently used library functions (for example under POSIX) that are based on system calls include the file processing functions open , close , read and write , as well as exec , fork or exit . These can be used by the programmer like normal user mode functions, but carry out a context change unnoticed in the background. The encapsulation of the system calls via an API completely frees the programmer from thinking about the internal functioning of the operating system or the hardware and allows more abstract software development.

Most of these POSIX functions have equivalent equivalents under Win32. time under POSIX corresponds to GetLocalTime under Win32 , for example .

implementation

The implementation of system calls depends heavily on the hardware used, the architecture and, ultimately, the operating system used. As a rule, a system call is now implemented with software interrupts or other special instructions from the CPU. In older systems, there is usually just a jump to a firmly defined address at which the system call or a jump command to this is implemented. For a programmer using the programming interface provided by the operating system, the implementation of system calls is irrelevant.

In the examples, an open file with the file descriptor / handle 15 is closed.

Linux

The Linux kernel houses a list of all system calls known to it, the so-called system call table . Each system call is assigned a unique number and an internal kernel function that is responsible for actually completing the required tasks. To make a system call, the number of the required call is stored in the EAX register of the CPU and then the software interrupt 128 (in hexadecimal notation 0x80) is triggered. Arguments to the system call are stored in the CPU registers according to the FastCall calling convention .

The software interrupt (also called exception ) interrupts program execution in user mode and forces an exception handler to be executed in kernel mode. This ensures the context change from an unprivileged ring to ring 0. The called exception handler is a function in the kernel that reads out the EAX register and then, if it contains a valid system call number, calls the corresponding kernel function from the system call table with the arguments in the other registers. After checking the arguments, the tasks requested from user mode are ultimately carried out by the kernel. If this function returns, the exception handler is also completed successfully and the normal program flow continues in unprivileged mode.

mov $6,  %eax    ; close() ist Systemaufruf 6
mov $15, %ebx    ; Dateideskriptor als erstes Argument
int $0x80        ; Softwareinterrupt auslösen

However, software interrupts only have a very slow execution speed. That is why both Intel and AMD have implemented commands in their x86 processors ( sysenter / sysexit or syscall / sysret , the latter two only from 64-bit architecture AMD64 ) that can execute the calls more quickly. However, since not every x86 processor supports a compatible command, the so-called vsyscall page is used in current Linux versions , in which the code suitable for the architecture used is stored. If a program now wants to execute a system call, it jumps to this memory page and continues the program flow there.

Unix and Unix variants

A so-called “ call gate ” is used in many Unix variants (e.g. older Solaris versions) . The application (in ring 3) uses a jump command to a special address that describes the call gate.

Call gates are faster than software interrupts (Cyrix 6x86: 23%), but require 7 instead of 2 bytes of code.

As an alternative, newer Solaris versions can handle software interrupts as well as Syscall and Sysenter commands.

Windows

System calls in Microsoft Windows are handled similarly as in Linux. The library function from the Windows API called in the program code is first converted internally into a call to the so-called Native API . There a unique number for each call is placed in the EAX register and a pointer to the arguments for the function is stored in the EDX register. Via the assembler instruction sysenter , control is passed from the user mode to the privileged kernel, which checks the parameters and then executes a kernel function assigned to the number in the EAX register.

 mov eax, 0x2f    ; NtClose() trägt die Nummer 0x2f in Windows Vista
 push 15          ; 15 auf den Stack legen
 mov edx, esp     ; Pointer auf 15 in EDX speichern
 sysenter         ; Systemaufruf durchführen

Commodore

The method of the early Commodore computers is an example of the way system calls work in older systems . The processors of the MOS Technology 6502 family used there did not yet distinguish between user mode and kernel mode and so it was possible to call the kernel-internal system call functions directly from the normal program flow. The only purpose of system calls at that time was therefore not to carry out activities that required certain privileges, but to provide a set of standardized functions implemented by the kernel that are independent of other libraries and should also be able to be used on later versions of the system (see also jump table ).

After placing the arguments of the function in the corresponding CPU register, the programmer could simply use the assembler command JSR ( J ump to S ub R outine ), followed by an address or a symbolic function name, to create one in the kernel address space Jump into the lying routine. At the time of Commodore BASIC 4.0 there were 28 system calls.

 LDA #15         ; 15 in das Register A legen
 JSR SYS4        ; Zur Kernel-Routine SYS4 (CLOSE) springen

Individual evidence

  1. A. Tanenbaum : Modern operating systems. Pearson Studium, 2009, ISBN 978-3-8273-7342-7 , p. 85.
  2. git.kernel.org (November 21, 2016)
  3. Windows X86 System Call Table (NT / 2000 / XP / 2003 / Vista / 2008/7/8) , accessed April 14, 2015
  4. A. Tanenbaum : Modern operating systems. Pearson Studium, 2009, ISBN 978-3-8273-7342-7 , p. 97.
  5. linux-magazin.de
  6. manugarg.googlepages.com
  7. commodore.ca Appendix H (June 21, 2007)