Linux is a free open-source operating system kernel that’s often used by web servers.
Linus Torvalds created linux in 1991 while a student at Helsinki university. He was frustrated at the lack of a free Unix system, so he decided to write his own [1, P. 3].
Although Linux is inspired by Unix and implements the Unix API (defined in the POSIX standard), it’s not a direct descendant of Unix [1, P. 3].
When people think of Linux, they often imagine a full Linux system including the kernel, the C library, and system utilities. Technically Linux is only the kernel, while the other features are part of the operating system [1, P. 4].
The kernel is the core functionality of an operating system. It provides an API for user interfaces to be written on top of. For example, interrupt handlers to handle signals (like a key press), a scheduler to manage processes, memory management to manage process address space, and services like networking [1, P. 5].
Typically a kernel runs with elevated privileges, like access to hardware memory. This execution state and memory space is known as kernel space. User applications run in user space. When a system is executing kernel code, it’s running in kernel mode, and when the kernel is executing a user application, it’s running in user mode [1, P. 5].
Programs running in user mode can communicate with the kernel using system calls: functions provided by the kernel that execute code in kernel mode [1, P. 5].
System calls are generally called as part of a function provided by a library, like the C library. Some C library functions do a lot of work before making a system call, like
printf(). Others are almost one to one mappings, like
open(). When an application calls a system call, we say that the application is executing a system call in user space, and the kernel is running in process context [1, P. 5].
The kernel manages the system’s hardware. Nearly all hardware uses interrupts to communicate with the kernel. When hardware sends an interrupt, the processor is interrupted and jumps to execute kernel code that was registered by the kernel on startup, known as an interrupt handler [1, P. 5]. For example, a keyboard might issue an interrupt when a key has been pressed to alert the kernel that there’s new data in the keyboard buffer. The kernel would use the interrupt number to execute the interrupt handler to process the new keyboard data and tell the keyboard control that it’s ready for more data [1, P. 5].
Interrupt handlers don’t run in a process context, they run in a special interrupt context. This exists so that the kernel can handle interrupts as quickly as possible [1, P. 5].
Linux is a monolithic kernel—it runs as a single process in a single address space. This is in contrast to microkernels, where kernel modules are separated into servers. Theoretically, most servers run as user processes in their own address space, although in practice the latency introduced by interprocess communication means that servers often run in kernel mode instead, defeating the main purpose of microkernels [1, P. 7].
Although Linux is similar to Unix, there are some notable differences:
- Linux can dynamically load and unload kernel modules.
- Linux can preempt a task as it executes.
- Linux doesn’t differentiate between threads and processes.
- Linux has an object oriented device model.
- Linux ignores some Unix features that it believes are badly designed, such as streams.
- Linux is free and open source.
-  L. R., Linux Kernel Development (Developer’s Library), 3rd ed. Addison-Wesley Professional, 2010.