|Operating Systems Development Series|
This series is intended to demonstrate and teach operating system development from the ground up.
We have covered alot of concepts in the previous tutorial. In this tutorial, we will continue looking at these concepts. We will be looking at alot of very important concepts in this tutorial. Heres whats on the menu for today:
Hardware AbstractionHardware Abstraction is very important. By now, you may know how complex hardware programming can be, and how very hardware dependent it is. This is where a Hardware Abstraction Layer (HAL) comes in. A HAL is a software abstraction layer used to provide an interface to the physical hardware. It is an abstraction layer. These abstractions provide a way to interact with devices, while not needing to know the details of a particular device or controller. Normally in modern OSs, the HAL is a basic Motherboard chipset driver. It provides a basic interface between the kernel and the hardware of the machine, including the processor. This is great, as the Kernel can interact with the HAL whenever it needs access to the hardware. This also means that the kernel can be completely hardware independent. This also allows us to think in terms of the device itself, rather then specific controllers or mappings. This helps make the kernel itself cleaner as well. Another great benefit comes from abstraction itself. If we decide to port our OS to a system with different hardware, all we need to do is develop a new HAL for it. This assumes that the HAL is designed very well to allow this. Most modern operating systems use a HAL in some way. We will also be developing a HAL to act as a motherboard chipset driver between the chipset hardware and the kernel. We will start developing on our HAL within the next tutorial, when we abstract the processor itself behind the HAL.
Kernel: A new perspectiveSo... What exactally is Kernel? Kernel is a Scheme like programming language developed by John N. Shutt (Serously ;) )
Anywhoo, lets look at another definition. A "Kernel" is the central component of a system. This system can be anything. The Kernel is the core of the system; it provides the very basic facilities for the management of effeciant execution of the system.In an operating system, this all-so-powefull Kernel provides the most basic interface to the system hardware and resources. It also provides the most basic management facilities, such as processor management, I/O management, memory management, and process management. The Kernel can contain more, depending on the complexity of the system being developed. Okay...The previous list might sound familiar...hm..Where have we seen that before? We actually looked at each inside of Tutorial 2. Lets look at this closer for better understanding.
Kernel: Putting everything together
Memory ManagementOkay, then! Remember again from Tutorial 2. We have created a basic list of items reguarding memory management and protection. Lets take another look at that again: Memory Management refers to:
Processor ManagementThis is a new one. As you know, the BIOS ROM initializes and starts up the primary processor. It only starts a single core. If you are running your OS on a system with a muticore processor, or a system with multiple processors, you will need to start up the other processors and cores manually. Letting applications play with the different processors at any time can cause fatal system problems. Because of this, we should never allow applications the ability to do this.
I/O Device ManagementSimular to physical memory, allowing applications direct access to controller ports and registers can cause the controller to malfunction, or system to crash. With this, depending on the complixity of the device, some devices can get surprisingly complex to program, and uses several different controllers. Because of this, providing a more abstract interface to manage the device is important. This interface is normally done by a Device Driver or Hardware Abstraction Layer. This allows us to think in terms of the device, rather then its details. Frequently, applications will require access to these devices. The Kernel must maintain the list of these devices by querying the system for them in some way. This can be done through the BIOS, or through one of the various system buses (Such as PCI/PCIE, or USB.) When an application requests an operation on a device (Such as, displaying a character), the kernel needs to send this request to the current active video driver. The video driver, in turn, needs to carry out this request. This is an example of Inter Process Communication (IPC).
Process ManagementThis is the most important task of the Kernel, and any computer for that matter. The Kernel needs a way of allocating execution time, and executing and management of different applications and processes. This is where Program Management, and Multitasking comes in. These terms should sound familiar from Tutorial 2. Lets take another look at that from tutorial 2: Program Management is responsible for:
The System APIBy now, you should start being able to understand how everything fits together, and where alot of the concepts from Tutorial 2 starts to come in. Yet, there is one little detail that we have not covered yet. How does the application ask the Kernel for request to a device or system resource? We have seen methods on how the OS manages and control the application, but how does the application control the system? This is where the system Application Programming Interface (API) comes in. The System API is an API that applications may use to interact with the Kernel and other system software. There are alot of methods for creating the System API. Most systems support System API routines through interrupts. For an example, The Linux Kernel System API primarily uses interrupt number 0x80 for system routines.
ConclusionWow, that is alot of stuff, huh? Dont worry if you dont understand this yet. Everything will be clear soon enough :)
Kernel Designs - Abstract: Primary Design ModelsBy now, you may start realizing how important Kernels are, and where they fit in. There has been alot of operating systems that have been developed using alot of different designs and setups. Alot of these designs have some simular basic concepts. There are alot of different ways to construct kernels. We will look some of the more used designs here.
Monolithic kernel Design
ExamplesSeveral large scale operating systems use a hybrid kernel, including but not limited to:
Microkernel ServersMicrokernel "Servers" are external programs that is granted special privileges by the kernel that normal programs do not have. These "privileges" may be direct access to hardware, or even physical memory. This allows server programs to enteract directly with the hardware devices they are controlling. Wait...It sounds like a device driver, doesnt it? Yep :) Thats basically what they are. Remember that microkernels are very minimal. They rely on external programs - servers - to help out. Servers needed by the kernel itself is normally loaded into memory before the kernel is executed. An example that will be needed is a file system server, that will contain the code for parsing the filesystem. Because the Kernel has no filesystem code, it has no way of loading the filesystem server! Because of this, it needs to be loaded before the kernel is executed. How can we do this? There are several ways. One method is loading a complete RAM image containing both the kernel and supported severs in it. Another method is simply loading the necessary servers at startup within the bootloader, and in someway giving the server information to the kernel upon executing. In both cases, the bootloader can determin what filesystem loading code to use, however the code can interact with the filesystem server without ever needing to load it in the first place! Cool, huh? Note: A "server" may also be called a "daemon".
Inter Process Communication (IPC)IPC is very important in microkernels. It allows seperate processes to communicate with each other, useually by sending messages, but it can also be envoked by using shared memory. There are alot of ways a process can "signal" another process. With reguards to microkernel severs, the most commonly used is also one of the easiest to understand - message passing. IPC allows the servers and kernel to interact with each other. Synchronous IPC In Synchronous IPC, The process sending the message is suspended until the other process responds. If the other process is busy, the message is stored in a queue for that process to act upon when ready. Asynchronous IPC Simular to Synchronous IPC, however both processes continue executing. That is, the process is not suspended.
Kernel Designs - Abstract: Secondary Design ModelsRemember that there are countless of ways that kernels may be designed. The following are common design models that are based off of the primary design models (Monolithic and Microkernels).
ExamplesSeveral large scale operating systems use a hybrid kernel, including but not limited to:
NanokernelNanokernels, also known as Picokernels, are a very small kernel. Normally, this would be a minimal microkernel structure. As the kernel itself is very small, it must rely on other software and drivers for the basic resources within the system.
ConclusionOkay, okay...I have to admit this tutorial is not that complex. It covers alot of very important topics that we needed to cover, however. Hopefully, this will help our readers gain a better understanding of kernels, and what they are responsible for. After all, this is what we will be building in the upcoming chapter and tutorials. Not just a kernel, but working on a basic hardware abstraction layer (HAL) for it as well. We will be developing a modified microkernel in this series. This will allow our readers to gain some experience and understanding in both monolithic and microkernel designs, as well as mixing the approches into a Hybrid Microkernel. In fact, our kernel will look simular to that is displayed in this tutorial. We will touch upon the full design of our kernel within the next tutorial, along with developing the basic building blocks for our HAL to abstract processor dependencies using C++. I will build several versions of the demos from now on to support multiple compiliers and platforms. As well as supporting both as C++ and as the C language. Cool?
Until next time,