5 System calls

A system call is request of system service. Unlike a normal subroutine, however, a system cannot just allow any user program to “call” kernel services. There are at least two reasons.

First, a user program runs at a low privilege level. However, services of a kernel need to run at a high privilege level. If a kernel service runs at a low privilege level, then many services cannot be performed. At the same time, a user program should not run at a high privilege level, as it may cause system wide problems in terms of stability, security and privacy.

Furthermore, when a system service is completed, control needs to be returned to a user program. Since a system service is performed at a high privilege level, this means that it has to be lowered when control is returned to a user program.

In other words, we need a mechanism to raise privilege level when a system service is performed, and a mechanism to return privilege level back to that of a user program when control is returned to a user program.

Well, we have just seen a mechanism like this, in the form of an interrupt and its corresponding ISR. The difference is that in the case of a hardware interrupt, it occurs asynchronouse to the execution of any program, user or system.

In the case of a system call, the interrupt occurs “synchronous” to a program. In other words, an interrupt is directly triggered by software. Such an interrupt is naturally known as a “software interrupt”. Many architectures (but not all) have a special instruction just to trigger a software interrupt. The x86 architure uses the int instruction to do this.

Each OS can choose to handle system calls differently. Linux chooses the interrupt vector 0x80 (128 in decimal) as the entry point to request a system service. All system services are requested via vector 0x80.

In order to differentiate the services requested, register eax gets a different value. For example, to read a file, register eax should be initialized to 3. If additional parameters are needed, other registers are used. In the case of reading a file, register ebx contains the file handle number, register ecx contains the number of bytes to (attempt to) read, and register edx contains the address in memory to read to.

Although a software interrupt is the mechanism to request system services, wrapper functions are defined to make system calls easier to C programmers. These system calls in C are no more than subroutines that load registers from parameters, perform the software interrupt, clean up the stack, and return to the caller.