OS development is a very interesting topic. Many programmers wish to develop their own simple OS, which is a very rewarding activity - especially as it teaches numerous concepts. I myself wrote my own toy OS when I was 17 and learned much from it. Even if you are not interested in the development side, knowing how your operating system works allows you to compare different ones and gives you some insight into it.
In this article I will explain some introductory concepts. It must be said, to try and explain how the OS works to a varied audience is very difficult. I will try to combine some general concepts with some more technical information for those interested. Future articles will go into aspects in more detail.The kernel
The Kernel is the core of an operating system. It is this component which is responsible for managing the hardware resources of the machine and provides a foundation upon which the rest of the operating system is built. Linux
(not GNU/Linux which is the whole operating system) is a kernel, initially written by Linus Torvalds in the early 1990s and now, via a world wide effort is a major OS component with over 10 millions lines of code. When writting a hobby operating system, the kernel is often the most important part.
There are two main kernel models (and lots of sub models too.) The first main model is the Monolithic
Kernel. In this model all the traditional kernel services (memory management, process management, file system support etc...) are all included inside the kernel itself and, more importantly run in kernel space. What this means for the user is that, as all the services are running inside kernel space, if there is an error or bug in one of them, it can bring down the whole kernel (and thus the machine.) A benefit of monolithic kernels is that there is often less overhead in their running. Examples of opertating systems employing monolithic kernels are MS Dos, Windows (95/98), GNU Linux
, Mac OS (versions 8.6 and below).
The other kernel model is a Micro
Kernel. In this model, the kernel is very small (only a couple of thousand lines of code, which can be often proven to contain no bugs.) Everything else is loaded modularly inside and run in userspace. The result is that, as there are clear restrictions placed upon userspace, any error/bugs in these services will be restricted to that module - the lightweight micro kernel can simply restart that service without any further hastle. The downside is that there are added design issues and there is often a performance hit. Examples of micro kernels include QNX, Amiga OS and Minix.
Im not sure if you have ever heard of the "Tanenbaum-Torvalds Debate" - in 1992 when Linus released his kernel, Andy Tanenbaum (writter of Minix and kernel expert) argued over monolithic and micro kernels, with Tanenbaum calling Linux's monolithic design obsolete and poor. One such copy of this can be found at http://oreilly.com/catalog/opensources/book/appa.html
Another interesting kernel (sub) model is that of an Exo
kernel. Exo-kernels are very small kernels, with the majority of services being implemented in user space libraries. The whole concept is to avoid any unnescesary abstractions being forced upon an application - instead they can choose which abstractions (via an os library) to use which often improves overhead and flexibility. In theory it can also improve portability. The downside of this sub model is that exo kernels still are not really tested, it can be difficult to ensure consistency and they can lead to a maintenance nightmare! Which language to use
Its certainly the case that not all languages are suitable for OS development. When developing an entire operating system it is likely that you will use a variety of languages, for different components.
Early kernels were written entirely in assembly code. However, assembly code is difficult to conceneptualise and unportable. Nowadays, C is the most popular language (although some embedded assembly is still required) for development. Having said that, there are other languages used for OS dev - such as C++, Lisp and FORTH. However, with all these higher level languages quite a lot of C and assembly code is required to "glue" the high level to the lower level machine, which results in more work. Interpreted languages (such as BASIC or Perl) are not suitable. What ever language you choose, it is important that there is some way of interfacing low level with the machine (which is why C is so popular.) Irrespective of the language, it is important that you understand how your architecture works.x86 Architecture Introduction
To allow you to understand how the x86 architecture (the most common machine architecture nowadays) loads and runs your OS, I will explain a little about it in this section.
When the machine is turned on it performs the Power On Self Test (POST), with the Basic Input Output System (BIOS) initialising certain machine items and detecting drives. The BIOS will search for a device which contains a Master Boot Record - this is a device with a boot sector (the start of you drive.) The boot sector is loaded into memory and then executed. By executing the MBR, control can be passed to your kernel. However, unfortunately, it isn't that simple.
When the 8086 can out in 1978 (which the modern x86 architecture is based upon) there was only one mode (later called real mode.) To allow for backwards compatability, ALL x86 processors will start in real mode (even nowadays), which is a 16 bit operating mode. The disadvantage of this mode is that less than 1MB of RAM can be accessed, there is no memory protection, there is no virtual memory, there are no restrictions on code execution and modern compilers can not work with this mode. In order to support more modern concepts the CPU also has a protected mode. Protected mode is the 32 bit "native" opertating mode of all x86 processors since the 80386. It allows for several virtual memory address spaces (up to 4GB in length), and strict process/memory management can be enforced.
In order to realise the full potential of your machine, it is therefore important to switch from real mode, to protected mode before loading your operating system. This is quite a technical issue, but basically involves setting up a memory Global Descriptor Table (GDT), Interupt Descriptor Table (IDT) and disable certain real mode items. More information is available at http://home.swipnet.se/smaffy/asm/info/embedded_pmode.pdfExamples
There are many many toy examples out there which you can play with. One such good example is the OsKit - http://wiki.osdev.org/OSKit
The next part of this article is OS Development 2 - Memory Management
Also read Unix Operating System - Introduction
Article Source: http://www.TechnicalTalk.net
*** Please do not forget to leave your comments about this article ***