Click here to Skip to main content
15,867,594 members
Articles / Containers / Virtual Machine

Operating System Development - Part 1

Rate me:
Please Sign up or sign in to vote.
4.39/5 (34 votes)
5 Jun 2008CPOL4 min read 70.5K   676   84   14
Environment settings for OS development

Introduction

In this first basic tutorial, I'll show how to make a very basic kernel and boot a system from a floppy disk with our kernel.

Even building a simple 'real mode hello world' kernel requires considerable amount of work to be done. To work with your own OS kernel in Windows environment is a little troublesome as most of the documents assume the development machine to be Linux.

I use Windows XP and to test my kernel I use Microsoft Virtual PC 2007. Testing the kernel in a virtual machine saves a lot of time. In the Floppy menu we can attach or release floppy image. Any file of length 1,474,560 can be used as a floppy image. The Virtual PC has a virtual hard disk with Windows XP installed (Actually DOS can do all we need- but I installed XP as I am used to it).

Some people prefer to write their own boot loader. But I prefer GRUB to load my kernel so that I can start right now writing code in kernel. GRUB is a very nice boot loader that supports a lot of file systems and file formats.

GRUB Setup

To setup GRUB, we need 2 floppy images:

  1. boot.img
  2. helper.img

The boot.img will be our boot disk and the other is used to create the boot disk.

Now we download the GRUB binary package grub-0.97-i386-pc.tar.gz and extract it. We get two files named stage1 and stage2 with other files.

Now we boot the Virtual PC with Windows XP and after that, attach the boot.img. Format the floppy and create a folder named 'system' on root of floppy. Copy the stage1 and stage2 files in system folder. Now release the boot.img and attach helper.img.

We need to concat the stage1 and stage2 files now and copy it on helper floppy starting from first sector as raw image. We concat them with the following DOS command:

>copy /b stage1 + stage2 grub.bin

Now using rawwrite.exe tool, copy the grub.bin in the 'helper' floppy. You may download this file from a lot of locations- some even have GUI.

Now shut down Windows XP and boot the Virtual PC with the helper floppy we just created. To do this, we must attach the floppy image before booting the Virtual PC. After the grub command prompt is shown, we release the helper.img and capture boot.img and on command prompt enter the following command.

grub>install (fd0)/system/stage1 (fd0) (fd0)/system/stage2

Now we have setup the boot disk. We now create our simple kernel to test this. The GRUB loader requires multiboot kernel (http://www.gnu.org/software/grub/manual/multiboot/multiboot.html). Here we build our multiboot kernel.

The Kernel

Here we define a very simple multiboot kernel that shows 'Hello World' on screen. We split the kernel into two files. One is in assembly and another in C. Infact we want to use C language as much as possible- but we need assembly a little. Not much.

Kernel.asm File

This file defines the multiboot header and calls the kernel_main function defined in C source file.

C++
[BITS 32]
[global start]
[extern _kernel_main] ; this is in the c file
    
    ; ----- Multiboot Header Starts Here -----

    MULTIBOOT_PAGE_ALIGN   equ 1<<0
    MULTIBOOT_MEMORY_INFO  equ 1<<1

    MULTIBOOT_HEADER_MAGIC equ 0x1BADB002
    MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO
    CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)

    ; The Multiboot header
    align 4
    dd MULTIBOOT_HEADER_MAGIC
    dd MULTIBOOT_HEADER_FLAGS
    dd CHECKSUM     

    ; ----- Multiboot Header Ends Here -----

start:
call _kernel_main
cli ; stop interrupts
hlt ; halt the CPU

To build assembly file, I use nasm.exe tool which is available for free. I prefer the ELF file format for my kernel.

>nasm -f elf kernel.asm -o ks.o  

Kernel.c File

This file defines clrscr, printxy and kernel_main functions.

C++
#define WHITE_SPACE 0x07
#define VIDEO_MEMORY 0xb8000

char *videoMemory = (char*) VIDEO_MEMORY;

void clrscr()
{
    int i;
    for(i=0;i < (80*25*2);i+=2)
    {
        videoMemory[i]=' ';
        videoMemory[i+1]=WHITE_SPACE;
    }
}

void printxy(char *message, unsigned int x, unsigned int y)
{
    unsigned int i=0;
    i=(y*80*2)+x;
    while(*message!=0)
    {
        if(*message=='\n')
        {
            y++;
            i=(y*80*2);
        } else {
            videoMemory[i++]=*message;            
            videoMemory[i++]=WHITE_SPACE;
        }
        *message++;
    }
}

kernel_main()
{
    clrscr();
    printxy("Hello World", 0, 0);
}

To compile C language files, I use DJGPP which is GCC port to Windows. It's a free tool and you can download after a search with Google. We compile with the following command line:

>gcc -c kernel.c -o kernel.o

Linking the Object Files

For linking, we also need the binutils tool for elf support. You can download from here.

We first define a linker script (link.ld file). It is very important as it helps to place the various sections in the right place.

OUTPUT_FORMAT("elf32-i386") 
ENTRY(start) 
phys = 0x00100000; 
SECTIONS 
{ 
.text phys : AT(phys) 
{ 
code = .; 
*(.text) 
*(.rodata) 
. = ALIGN(4096); 
} 
.data : AT(phys + (data - code)) 
{ 
data = .; 
*(.data) 
. = ALIGN(4096); 
} 
.bss : AT(phys + (bss - code)) 
{ 
bss = .; 
*(.bss) 
. = ALIGN(4096); 
}

.rodata : AT(phys + (rodata - code)) 
{ 
rodata = .; 
*(.rodata) 
. = ALIGN(4096); 
}
 
end = .; 
} 

OK. We are almost done and use the following command to build our kernel (kernel.bin).

>ld-elf -T link.ld --oformat elf32-i386 -o kernel.bin ks.o kernel.o

To see if the file is created correctly, we can use the following command:

>objdump-elf kernel.bin --all

Booting with Kernel

Now we copy the kernel.bin to our boot disks system folder and boot with that disk. When GRUP command prompt comes, we type in the following command:

grub>kernel /system/kernel.bin

The grub shows information about our multiboot-elf kernel information. Now we do the following command:

grub>boot

Walllla- the Hello World message is shown. Please note here that GRUB already has set Protected Mode, GDT and A20 gate things. The reason why the printing works is GRUB has setup GDT in such a way that Virtual Memory and Physical Memory to video memory is exactly the same.

Conclusion

This is a very basic tutorial and a really old topic. I just wanted to provide what we need to start writing our own OS. The next part may cover some advanced features like protected mode and descriptor tables and the next some more advanced topics. Please give your comments so that I can improve this article and try to provide better information in the next article.

Also please note that the contents of this article are not mine. I just collected the manuals and tutorials and added them up. The main intention was to setup the basic environment.

History

  • 5th June, 2008: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer Microsoft
United States United States
Have completed BSc in Computer Science & Engineering from Shah Jalal University of Science & Technology, Sylhet, Bangladesh (SUST).

Story books (specially Masud Rana series), tourism, songs and programming is most favorite.

Blog:
Maruf Notes
http://blog.kuashaonline.com

Comments and Discussions

 
QuestionQuestion on 4096 bytes per sector Pin
Deji Adegbite12-Nov-11 14:18
Deji Adegbite12-Nov-11 14:18 
QuestionWho was the first? Pin
Sergey Nikulov28-Oct-08 21:31
Sergey Nikulov28-Oct-08 21:31 
AnswerRe: Who was the first? Pin
Maruf Maniruzzaman29-Oct-08 7:01
Maruf Maniruzzaman29-Oct-08 7:01 
GeneralInteresting Pin
merlin98111-Jun-08 3:49
professionalmerlin98111-Jun-08 3:49 
GeneralRe: Interesting Pin
Maruf Maniruzzaman11-Jun-08 18:19
Maruf Maniruzzaman11-Jun-08 18:19 
GeneralRe: Interesting Pin
alexiev_nikolay8-Jul-08 10:28
alexiev_nikolay8-Jul-08 10:28 
GeneralRe: Interesting Pin
ztttt11-Jul-08 23:51
ztttt11-Jul-08 23:51 
GeneralRe: Interesting Pin
MasterGUI5-Nov-08 14:21
MasterGUI5-Nov-08 14:21 
GeneralStack problem Pin
zzmike9-Jun-08 19:13
zzmike9-Jun-08 19:13 
QuestionRe: Stack problem Pin
vobject13-Oct-09 3:24
vobject13-Oct-09 3:24 
What do you mean with "setup esp"? push esp?
And what could be the problem if it is missing?

Thanks.
QuestionI want to boot OS from U-disk, do you know how to program the u-disk sector directly? Pin
lsmhg9-Jun-08 17:19
lsmhg9-Jun-08 17:19 
Generalit's an useful article Pin
jackyxinli5-Jun-08 15:21
jackyxinli5-Jun-08 15:21 
GeneralRe: it's an useful article Pin
Maruf Maniruzzaman5-Jun-08 16:20
Maruf Maniruzzaman5-Jun-08 16:20 
GeneralRe: it's an useful article Pin
MasterGUI5-Nov-08 14:30
MasterGUI5-Nov-08 14:30 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.