Wednesday, February 26, 2014

How can we detect the memory?(DAY 11)


Lets watch the following video before we go ahead with memory management. The video clip is from a famous TV series "NEWSROOM".


If you saw that video then the person sitting in the center quotes "first step in solving any problem is in recognizing that there is one". This part of the tutorial is inspired by that quote. 


"first step in managing memory is in recognizing that there is one"



To accomplish this grub comes to our rescue. So how exactly the grub loader help us in this.

Once the operating system is loaded by the grub and its execution starts, the EBX register contains the physical address of a Multiboot information data structure. Through this information the boot loader communicates important information to the operating system. The Multiboot information is placed anywhere in memory by the boot loader (with the exception of the memory reserved for the kernel and boot modules, of course). The operating system uses this information to detect the memory.

Steps that should be followed :-

1) Create a file with name multiboot.h.
2) Copy the code on this page and paste it in multiboot.h.
3) Save it in the same folder where your kernel.c lies.
4) Edit the kernel.c

//add this 
#include "multiboot.h"
//change the kernel_main function
void kernel_main(multiboot_info_t* mbd,unsigned int magic)
{
//Now we have the memory information with us.
//Use your printf function to print the data here.
}

5) To understand each part of multiboot.h you should go through this. Basically the "multiboot.h" has the structure of how the memory map is stored in memory. You get a pointer to that memory section through "mbd" variable. If you understand pointers in C then it won't be difficult to get the memory map.
6) Print each value. Then you will find that the values are consistent with the memory you allocated for this virtual machine (Note: you have to patiently check the values as they involve a lot of calculations). You should also go through this to understand what part of memory is usable.

Thursday, February 20, 2014

Memory Management (Day 10)

I expect that you have written your own printf function which is way better than printf I wrote in my previous post. Also write a scanf function if you get time. Writing a scanf function is not going to be tough. First step would be to find the interrupt which is there for keyboard. Then use this interrupt to get keyboard input. Once you have the keyboard input, use the your printf function to print the data on screen.

Have a look at standard C implementation of printf and scanf for writing a good printf and scanf function of your own.

Today we will move on to next important topic of operating system development which is memory management. I have shared a link to a book which I found very interesting. I hope you should read it too. It's the first (1) link. It is about memory management.

Following are the few questions that you need to answer so that you can write your own memory manager.

Why is memory management required? 

Following question will be explained in detail in my next few posts...

How can we detect the memory?
Here GRUB will come to our rescue.

What part of the memory is usable?
Not all the memory you have is usable. We need to find out the part which is usable.

How should we manage memory?
In this I will explain paging and segmentation which are very important concepts in operating system management.

Friday, February 14, 2014

"Hello World" Program!!! (Day 9)

Today we are going to see our operating system print "Hello world" on the screen.

Software that you need to install are xorris and grub

sudo apt-get install xorris
sudo apt-get install grub

Create a file grub.cfg and paste the code given below. Instead of myos you can give any name that suits you.

menuentry "myos" {
 multiboot /boot/myos.bin
}

Following is a shell script file which will compile the OS code and generate bootable image. We are using this file because there are many steps involved in compilation and you may not want to go through each step every time you make changes to the code.


#!/bin/sh
export PREFIX="$HOME/opt/cross"
export TARGET=i586-elf
export PATH="$PREFIX/bin:$PATH"
i586-elf-gcc -c kernel.c -o kernel.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra
i586-elf-as boot.s -o boot.o
i586-elf-gcc -T linker.ld -o myos.bin -ffreestanding -O2 -nostdlib boot.o kernel.o -lgcc
mkdir -p isodir#comment this line when you use this file again to compile your code.
mkdir -p isodir/boot#comment this line when you use this file again to compile your code.
cp myos.bin isodir/boot/myos.bin
mkdir -p isodir/boot/grub#comment this line when you use this file again to compile your code.
cp grub.cfg isodir/boot/grub/grub.cfg
grub-mkrescue -o myos.iso isodir

Save the above commands in a file with name "build" in the same folder where your rest of the code resides.
Now execute the following code in the terminal.
chmod +x build
./build

Now your bootable OS image is ready. Your next step is to start is to start virtualbox
sudo virtualbox

Create your new virtual machine using virtual machine wizard. Virtual machine should have the following configuration because we are going to analyse the memory and my calculation will depend on this configuration.



 Select the myos.iso as your bootable image file and run it. This what you will see.


So finally we are done with this hello world program. I hope you enjoyed OSDEVING. Make sure you continue with it. We are going to do a lot more interesting stuff soon. Our next step is to analyse the memory we have and how to manage it. Will be back soon with the next tutorial.
HAPPY OSDEVING!!

"Hello World" Program!!! (Day 8)

In the last tutorial we didn't compile the C code. I'll give the commands for that in the next tutorial. For now you should save that file as kernel.c.

Now you have a the C part and an assembly part. What we need next is something which can link these two so that assembly code can call a C function. To link these we use linker.

Wikipedia definition:
A linker  is a computer program that takes one or more object files generated by a compiler and combines them into a single executable program. 

After compiling kernel.c and boot.s we will get object files kernel.o and boot.o. We are going to link these object files. To link these we need a linker script which tells how to link these files. The linker file is here.  Download the code and save it as linker.ld in same folder where kernel.c and boot.s reside.

Also read more about how to write a linker script and also find out what each part of the linker file means. Read more about linker here.

Monday, February 10, 2014

"Hello World" Program!!! (Writing C code!! Day 7) your own printf function

So let us start with a basic printf which will print hello world to the screen.
Remember that you can't use header files which you normally use in C programming (for example stdio.h) as they are not yet supported by the OS of this new system. But there are some header files which come with every compiler and standard across all type of compilers. In this case stddef.h stdint.h are two examples.
There is particular location in memory from which the data which needs to be displayed on the screen is read.
The memory location of this video buffer is stored in "buffer" variable.
Initially the assembly code calls kernel_main and the C code starts calling
Then we initialize screen to look black which is done in the cleanTheScreen() call
After which we call printf() which prints hello world to the screen.
Here you will see a lot of new data types which may be scary who have are still learning C programming. These new data types are used so that we are sure about the amount of space that is going to be allocated for these variables.

Make sure you write your own code which uses concepts explained in this code.
Following are the color code for various colors you can use in place of black and white we are using here in the code. BLACK = 0,
BLUE = 1,
GREEN = 2,
CYAN = 3,
RED = 4,
MAGENTA = 5,
BROWN = 6,
LIGHT GREY = 7,
DARK GREY = 8,
LIGHT BLUE = 9,
LIGHT GREEN = 10,
LIGHT CYAN = 11,
LIGHT RED = 12,
LIGHT MAGENTA = 13,
LIGHT BROWN = 14,
WHITE = 15,

#include 
#include 
//lets store the screen size in a global variable
static const size_t SCREEN_WIDTH = 80;
static const size_t SCREEN_HEIGHT = 24;
uint8_t screen_color = 0;//0x0
uint8_t text_color = 15;//0xf
uint16_t* buffer = (uint16_t*) 0xB8000;//pointer which points to the display memory. Display reads from this memory

int cleanTheScreen()
{
    size_t row = 0;
    size_t column = 0;
    char text = ' ';
    uint16_t color = screen_color;
    size_t position ;
    while(row < SCREEN_HEIGHT)
    {
        while(column < SCREEN_WIDTH)
        {
             position  = row*SCREEN_WIDTH+column;
             buffer[position] = text|screen_color<<8;
             column++;
        }
        row++;
    }
}
int printf(char* data,)
{
    uint8_t row = 0;
    uint8_t column = 0;
    size_t row = 0;
    size_t column = 0;
    char text = ' ';
    uint16_t color = text_color;
    size_t position ;
    while(column < SCREEN_WIDTH)
    {
         position  = row*SCREEN_WIDTH+column;
         buffer[position] = text|screen_color<<8;
         column++;
    }
}
void kernel_main()
{

 cleanTheScreen();
 printf();
}

"Hello World" Program!!! (Writing C code!! Day 6)

Finally something which we will understand clearly.... "C code". In the previous tutorial we wrote assembly code in which at the end there was a call kernel_main. This assembly code calls the kernel_main() function in the C program. This is where your c code starts executing.

As we had discussed earlier there will be no in built printf function or scanf function. You have to implement everything on your own. So before you get started you may want to have some tool to debug your code. Normally common people use printf to do that. But we don't have a printf function. So let us build a printf function first.

Few questions that may come up and they should actually:-

  1. What things we need to print hello world on the screen?
  2. What part of memory should we write the text to?
  3. How to choose color?
  4. What should we write?
  5. OS which I am using right now has better looks what should I do to make my screen display content better?
We will go through these one by one!!! It would nice if you try to find answers to these questions on your own. Don't worry if you get answers. Answer to last question is an advanced topic which will be covered some time later.

Sunday, February 9, 2014

"Hello World" Program!!! (Writing assembly code!! Day 5)

So from now on we will follow the steps mentioned in the previous post. Today we will write a bit of assembly code 

First few questions that came to my mind when I started writing the hello world program were
#)Why do we need assembly code!!??
#)Why cant we just start with C program?
Few reasons for these questions are:
1) You cannot enter protected mode with just C (I mentioned about protected mode in my previous posts).
2) Putting the multiboot header in the right section.
Multiboot header is something which tells the GRUB that  
3) setting up the stack etc. 
If you know other reasons please post them in the comment section.

Assembly code is here. You have to use the code from that page.  Save the code as "boot.s"
Then compile it using the following command. But this code wont compile It has errors. The code has error some where. Hence use this code instead.

#remember that every time you want to compile the code you develop you should set the environment variables in the terminal as given below

export PREFIX="$HOME/opt/cross"
export TARGET=i586-elf  
export TARGET=i586-elf 
export PATH="$PREFIX/bin:$PATH"

# The reason why you do this is because without these the computer will not  know which compiler to use and it will use your default compiler which is not meant to compile code for the new operating system you are developing.
#after these steps execute the following command after you cd to the folder which contains boot.s

i586-elf-as boot.s -o boot.o

For now and I think for a very long time you are free from this assembly language. You don't have to worry about this any more.