• In a Unix/Linux system, several concurrent processes attend to different tasks. • Each process asks for system resources, be it computing power, memory, network connectivity, or some other resource. • The kernel is the big chunk of executable code in charge of handling all such requests. • Although the distinction between the different kernel tasks isn’t always clearly marked, the kernel’s role can be split into the following parts: A split view of the Kernel Process management • The kernel is in charge of creating and destroying processes and handling their connection to the outside world (input and output). • Communication among different processes (through signals, pipes, or interprocess communication primitives)is basic to the overall system functionality and is also handled by the kernel. • In addition, the scheduler, which controls how processes share the CPU, is part of process management. • More generally, the kernel’s process management activity implements the abstraction of several processes on top of a single CPU or a few of them. Memory management • The computer’s memory is a major resource, and the policy used to deal with it is a critical one for system performance. • The kernel builds up a virtual addressing space for any and all processes on top of the limited available resources. • The different parts of the kernel interact with the memory-management subsystem through a set of function calls. File systems • Unix is heavily based on the file system concept. • Almost everything in Unix can be treated as a file. • The kernel builds a structured file system on top of unstructured hardware, and the resulting file abstraction is heavily used throughout the whole system. • In addition, Linux supports multiple file system types, that is, different ways of organizing data on the physical medium. For example, disks may be formatted with the Linux-standard ext3 file system, the commonly used FAT file system or several others. Device control • Almost every system operation eventually maps to a physical device. • With the exception of the processor, memory, and a very few other entities, any and all device control operations are performed by code that is specific to the device being addressed. That code is called a device driver. • The kernel must have embedded in it a device driver for every peripheral present on a system, from the hard drive to the keyboard and the tape drive. Networking • Networking must be managed by the operating system, because most network operations are not specific to a process: incoming packets are asynchronous events. • The packets must be collected, identified, and dispatched before a process takes care of them. • The system is in charge of delivering data packets across program and network interfaces, and it must control the execution of programs according to their network activity. • Additionally, all the routing and address resolution issues are implemented within the kernel. Loadable Modules • One of the good features of Linux is the ability to extend at runtime the set of features offered by the kernel. • This means that you can add functionality to the kernel (and remove functionality as well) while the system is up and running. • Each piece of code that can be added to the kernel at runtime is called a module. • The Linux kernel offers support for quite a few different types (or classes) of modules, including, but not limited to, device drivers. • Each module is made up of object code (not linked into a complete executable) that can be dynamically linked to the running kernel by the insmod program and can be unlinked by the rmmod program. Classes of Devices and Modules • The Linux way of looking at devices distinguishes between three fundamental device types. • Each module usually implements one of these types, and thus is classifiable as a char module, a block module, or a network module. • This division of modules into different types, or classes, is not a rigid one; the programmer can choose to build huge modules implementing different drivers in a single chunk of code. • Good programmers, nonetheless, usually create a different module for each new functionality they implement, because decomposition is a key element of scalability and extendibility. Character devices • A character (char) device is one that can be accessed as a stream of bytes (like a file). A char driver is in charge of implementing this behavior. • Such a driver usually implements at least the open, close, read, and write system calls. The text console (/dev/console) and the serial ports (/dev/ttyS0 and friends) are examples of char devices, as they are well represented by the stream abstraction. • Char devices are accessed by means of filesystem nodes, such as /dev/tty1 and /dev/lp0. • The only relevant difference between a char device and a regular file is that you can always move back and forth in the regular file, whereas most char devices are just data channels, which you can only access sequentially. Block devices • Like char devices, block devices are accessed by filesystem nodes in the /dev directory. • A block device is a device (e.g., a disk) that can host a filesystem. • In most Unix systems, a block device can only handle I/O operations that transfer one or more whole blocks, which are usually 512 bytes (or a larger power of two) bytes in length. • Linux, instead, allows the application to read and write a block device like a char device—it permits the transfer of any number of bytes at a time. • As a result, block and char devices differ only in the way data is managed internally by the kernel, and thus in the kernel/driver software interface. • Like a char device, each block device is accessed through a filesystem node, and the difference between them is transparent to the user. • Block drivers have a completely different interface to the kernel than char drivers. Network interfaces • Any network transaction is made through an interface, that is, a device that is able to exchange data with other hosts. • Usually, an interface is a hardware device, but it might also be a pure software device, like the loopback interface. • A network interface is in charge of sending and receiving data packets, driven by the network subsystem of the kernel, without knowing how individual transactions map to the actual packets being transmitted. • Many network connections (especially those using TCP) are stream-oriented, but network devices are, usually, designed around the transmission and receipt of packets. • A network driver knows nothing about individual connections; it only handles packets. • Not being a stream-oriented device, a network interface isn’t easily mapped to a node in the filesystem, as /dev/tty1 is. • Communication between the kernel and a network device driver is completely different from that used with char and block drivers. • Instead of read and write, the kernel calls functions related to packet transmission. • There are other ways of classifying driver modules that are orthogonal to the above device types. In general, some types of drivers work with additional layers of kernel support functions for a given type of device. • Other classes of device drivers have been added to the kernel in recent times, including FireWire drivers and I2O drivers. • In the same way that they handled USB and SCSI drivers, kernel developers collected class-wide features and exported them to driver implementers to avoid duplicating work and bugs, thus simplifying and strengthening the process of writing such drivers.