Concepts of Programming

System Programming Foundations

System programming in Linux is built on three pillars: system calls, the C library, and the C compiler. Each one is deserving of an introduction.

Calls to the system

System calls are the beginning and finish of system programming. System calls (commonly abbreviated as syscalls) are function calls made from user space—your text editor, favourite game, and so on—into the kernel (the operating system’s fundamental internals) to seek a service or resource from the operating system. Read() and write() are two examples of common system calls, while get thread area() and set tid address() are more unusual ().

Most other operating system kernels implement significantly fewer system calls than Linux. For example, the number of system calls on the x86-64 architecture is under 300, compared to the thousands of system calls on Microsoft Windows. Each computer architecture (such as Alpha, x86-64, or PowerPC) can supplement the standard system calls with its own in the Linux kernel. As a result, system calls accessible on one architecture could not be the same as those available on another. Nonetheless, all architectures implement a high percentage of system calls (more than 90%). This book will look at the shared subset of common interfaces.

System calls are invoked.

It is not feasible to connect user-space and kernel-space apps directly. User-space apps must not be able to now execute kernel code or change kernel data for security and reliability concerns. Instead, the kernel must provide a means for a user-space programme to “signal” that it wants to make a system call to the kernel. The application can then use this well-defined technique to trap into the kernel and execute just the code that the kernel permits. The actual mechanism differs from one design to the next. A user-space application on i386, for example, runs the int software interrupt instruction with the value 0x80. This instruction causes the kernel to enter kernel space, the kernel’s protected domain, where a software interrupt handler is executed—and what is the handler for interrupt 0x80? The system call handler, of course!

The application uses machine registers to inform the kernel which system call to run and what parameters. System calls are signified by a number, which starts at 0 and goes up from there. The user-space programme stuffs 5 in register tax before issuing the int instruction on the i386 architecture to request system call 5 (which happens to be open()).

Similarly, parameter passing is handled. On the i386, for example, a register is utilised for each conceivable parameter—the first five arguments are stored in registers in that sequence. A single record refers to a buffer in user space where all parameters are saved in the uncommon case of a system call with more than five arguments. Most system calls contain only a few parameters.

Although the principle is the same, some architectures handle system call invocation differently. You normally don’t need to know how the kernel handles system call requests as a system programmer. This knowledge is contained in the architecture’s standard calling conventions, which the compiler and C library handle automatically.

The C Library is a collection of C programmes.

Unix applications rely heavily on the C library (libs). Even if you’re writing code in another language, the C library is almost certainly there, wrapped by higher-level libraries and providing fundamental functions and allowing system call invocation. GNU libc, abbreviated Glibc and pronounced gee-lib-see or, less usually, glib-see, provides the C library on current Linux systems.

The GNU C library offers far more than its name implies. Glibc provides wrappers of system calls, threading support, and basic application features and provides the standard C library.