20096 total geeks with 3178 solutions
Recent challengers:
 Welcome, you are an anonymous user! [register] [login] Get a yourname@osix.net email address 

Articles

GEEK

User's box
Username:
Password:

Forgot password?
New account

Shoutbox
Domuk
No, not an issue with the PHP - I was responding to "AJAX not being cross site is annoying"
MaxMouse
Really? i thought that would only be important if the user had some kind of control over where the XML came from, if you hard code it (As in a PHP file) wouldn't that eliminate XSS attacks?
Domuk
Yes, but very, very necessary. AJAX requests run in the context of the browser, there'd be no security if it was cross-domain .
MaxMouse
AJAX not being cross site is annoying, all other scripts can be used in that way, having to resort to PHP to patch it is a shame.
SAJChurchey
thx MaxMouse

Donate
Donate and help us fund new challenges
Donate!
Due Date: Nov 30
November Goal: $40.00
Gross: $0.00
Net Balance: $0.00
Left to go: $40.00
Contributors


News Feeds
The Register
MySpace makes peace
with Indies
Nvidia previews
next-gen Fermi GPUs
Potty-mouths
charged for Comcast
hijack
Microsoft
Silverlight - now
with hidden Windows
bias
Apple cult leader
emails outside
world
Sony demos monster
3D TV
Wrecking CRU:
hackers cause
massive climate
data breach
Skinny Acer
notebook delivers
six-day battery
life
VTOL gyro-copter
flying car mates
with killer robot
Oracle begs EC for
more time
Slashdot
iPhone Owners
Demand To See Apple
Source Code
Proton Beams Sent
Around the LHC
Microsoft"s Lack of
Nightly Builds For
IE
Some Claim Android
App Store Worse
Than iPhone"s
Climatic Research
Unit Hacked, Files
Leaked
Aging Nuclear
Stockpile Good For
Decades To Come
Netbooks Have
Higher Failure Rate
Than Laptops
Xbox Live Class
Action Being
Investigated
Patent Issued For
Podcasting
Linus Torvalds For
Nobel Peace Prize?
Article viewer

Mini OS

Written by:dimport
Published by:bb
Published on:2003-06-21 07:19:46
Topic:Assembly
Search OSI about Assembly.More articles by dimport.
 viewed 28749 times send this article printer friendly

Digg this!
    Rate this article :
This tutorial will take you through building your own mini Operating System and outputting the hello world message.

First thing we need to create a boot sector. Because CPU is loading in 16 bit mode,
to create a boot sector we need to use assembler and a linker from bin86 package.
There are of course alternatives, but the tutorial will be created using examples from this package.
The syntax for this assembler combining common characteristics for Intel and AT&T and might
seem a little strength, however you'll get used to it.



1. Boot sector (boot.s)
I will not write the full source for the program, so that you will understand the basic idea better.
First of all, we should define the general constants:



START_HEAD = 0 - The device head, we will be using.

START_TRACK = 0 - The track, we start reading from.

START_SECTOR = 2 - The sector, we will start reading the OS from

SYSSIZE = 10 - The size in sectors (1 sector = 512 byte)

FLOPPY_ID = 0 -The ID of the drive (0 - is first, 1 is second)

HEADS = 2 - Number of heads

SECTORS = 18 - Number of sectors for a floppy ( 18 for 1.44 Mb)

While booting the following will happen:
The BIOS loader reads first sector of the floppy and will put it in 0000:0x7c00
and will move there the control. We'll get it and, first, we should move ourselves
lower to the address 0000:0x600 move there and continue. All we really need to do
is to boot the kernel ( sector 2-12 on the first track of the floppy with the address
0x100:0000, moving into protected mode and jumping to the first rows of the kernel.
Because of this, we'll need to declare few more constants:



BOOTSEG = 0x7c00 - We will put the booting BIOS sector here

INITSEG = 0x600 - Here we will move it

SYSSEG = 0x100 - Our kernel will go here

DATA_ARB = 0x92 - The definer of data segment for descriptor

CODE_ARB = 0x9A - The definer of code segment for descriptor

First of all, we should move ourselves into more appropriate place:


 cli
 
 xor ax,ax
 
 mov ss,ax
 
 mov sp, #BOOTSEG
 
 mov si, sp
 
 mov ds, ax
 
 mov es, ax
 
 sti
 
 cld
 
 move di, #INITSEG
 
 mov cx, #0x100
 
 repnz
 
 movsw
 
 jmpi go, #0 ; jump into new place of the boot sector , mark "go"
 
 Now we have to configure data segments (es,ds)
 
 go:
 
 mov ax, #0xF0
 
 mov ss,ax
 
 mov sp, ax
 0xF0:0xF0=0xFF0
 
 mov ax, #0x60 ;we'll set data segments in 0x60
 
 mov ds,ax
 
 mov es,ax

Finally, we can output the message. Because we have the whole BIOS
we can use the prepared function 0x13 of interrupt 0x10. We could
of course cut it and write directly into Video memory, but we only
have 512 bytes, which is not a lot. We'd rather spend it on something else.
mov cx,#18

mov bp,#boot_msg

call write_message


The function write_message looks like this:

 write_message:
 
 push bx
 
 push ax
 
 push cx
 
 push dx
 
 push cx
 
 mov ah, #0x03; read the current cursor position, so that we don't output the message anywhere.
 
 xor bh,bh
 
 int 0x10
 
 pop cx
 
 mov bx,#0x0007 ; parameters of outputted symbols: videopage 0, attribute 7 (black and grey)
 
 mov ax,#0x1301 ; outputting prompt and moving cursor
 
 int 0x10
 
 pop dx
 
 pop cx
 
 pop ax
 
 pop bx
 
 ret
 
 



and message is like this:

 boot_msg:
 
 .byte 13,10
 .ascii "Booting MiniOS..."
 .byte 0
 

By this time we will have message "Booting MiniOS..." displayed on the screen.
This is much better than hello world :).

(BOOT.S)
Now, as we have our loader, we move into protected mode and output program written in C.
The kernel is 32 bit. It will be placed separately from the boot sector and built with
gcc and gas. The syntax of assembler gas is compatible with AT&T standard,
so it will be much simpler. But first we need to read kernel. Again, we'll
use a prepared function 0x2 of interrupt 0x13.

 recalibrate:
 
 mov ah, #0
 
 mov dl, #FLOPPY_ID
 
 int 0x13 ; drive reinitialisation
 
 jc recalibrate
 
 call read_track ; calling kernel reading function
 
 jnc next_work ; if nothing bad happens, continue working
 
 bad_read ; if reding is not successful, output error
 
 mov bp,#error_read_msg
 
 mov cx, 7
 
 call write_message
 
 inf1: jmp inf1 ; going to endless loop, so that we can be saved by "hand" rebooting only.
 

The actual reading function is very simple. We should "memorise" parameters and
the read the kernel in one go. The difficulties will begin when the kernel wont
be able to fit in 17 sectors (i.e. 8.5 Kb); But this is in the future and now we
shouldn't have troubles with that!

 read_track:
 
 pusha
 
 push es
 
 push ds
 
 mov di, #sysseg
 
 mov es, di ; the data buffer address
 
 xor bx,bx
 
 mov ch, #START_TRACK ; track 0
 
 mov c1, #START_SECTOR ; start from sector 2
 
 mov dl, FLOPPY_ID
 
 mov dh, #START_HEAD
 
 mov ah, #2
 
 mov al, #SYSSIZE ; read 10 sectors
 
 int 0x13
 
 pop ds
 
 pop es
 
 popa
 
 ret
 

That's it, kernel is read successfully, and we can output one more message:)

 next_work:
 
 call kill_motor ; stop floppy drive
 
 mov bp,#load_msg ; output message
 
 mov cx,#4
 
 call write_message
 
 this is the message, you want to output
 
 load_msg:
 
 .ascii "DONE"
 
 .byte 0
 
 And here how you stop floppy:
 
 kill_motor:
 
 push dx
 
 push ax
 
 mov dx,#0x3f2
 
 xor al,al
 
 out dx,al
 
 pop ax
 
 pop dx
 
 ret
 


No, you should see the following on your monitor "Booting MiniOS...DONE" and the lame
of your floppy drive should be off. Ok, now is the most important bit, jump
into protected mode. First of all, we should turn on the address line A20. It
means that we'll be using 32 bit data addressing.

  mov al, #0x01 ; the recording command for 8042
 
 out #0x64, al
 
 mov al, #0xDF
 
 out #0x60, al
 

Show to everyone, that we are moving into protected mode, so that everyone knows how 31337 we are:).

 protected_mode:
 
 mov bp,#load_msg
 
 mov cx, #25
 
 call write_message
 
 the message
 
 load_msg:
 
 .byte 13,10
 
 .ascii "Going to protected mode..."
 
 .byte 0
 

While the BIOS is still alive, we should save the cursor position and save it in (0000:0x8000).
Kernel will use this data after.

 save_cursor:
 
 mov ah,#0x03 ; read cursor position
 
 xor bh, bh
 
 int 0x10
 
 seg cs
 
 mov [0x8000], dx ; save into special hidden place
 

Now, ATTENTION , restrict interrupts and load descriptors table.


cli

igdt GDT_DESCRIPTOR ; load descriptors table description

The descriptors table consists of 3 describers: zero ( should present always), code segment and data segment.

.align 4

.word 0

GDT_DESCRIPTORS: .word 3*8-1 ; descriptors table size

.long 0x600 + GDT ; location of descriptors table

.align 2

GDT:

.long 0,0 ; e.g. 0 : empty descriptor

.word 0xFFFF, 0 ; number 8: code descriptor

.byte 0, CODE_ARB, 0xC0, 0

.word 0xFFFF, 0 ; number 0x10 : data descriptor

.byte 0, DATA_ARB, 0xCF, 0



Moving into protected mode may implemented in (at minimum) two ways. We
will be using command lmsw, just like
in Linux.

mov ax, #1

lmsw ax ; later real mode : now we are in a protected mode

jmpi 0x1000, 8 ; Long jump onto 32 bit kernel


At the end of the assembly file you could also add:
.org 511
.end_boot: .byte 0
As a result, your file will be exactly 512 byte.


That's it, we are done!!! Now we say good buy to it and move onto kernel.




(START.C)
Unfortunately, the kernel must also start from assembler. However now it wont be so much of it.
We should set the correct values of segments for data. (es, ds, fs, gs) Saving there the
value of respective data descriptor.

 cld
 
 cli
 
 movl $(___KERNEL_DS),%eax
 
 movl %ax,%ds
 
 movl %ax,%es
 
 movl %ax,%fs
 
 movl %ax,%gs
 

No we check, whether address line A20 is turned on correctly with a simple writing methd.
For the experiment to be successful we should zero flags

 xorl %eax,%eax
 
 1: incl %eax
 
 mov %eax,0x000000
 
 cmpl %eax,0x100000
 
 je 1b
 
 pushl $0
 
 popfl
 

Now we call the function, written in C.

call SYMBOL_NAME (start_my_kernel)

And that's it

inf: jmp inf





Now we are almost back to what we started from. Almost, because we now need to create printf
"by hands". Because there are no interrupts, we will be writing directly into video memory.
I will "borrow" the code for this part from Linux (arch/i386/boot/compressed) with minor
changes. For assembling you'll need
The following macros: inb(), outb(), inb_p(), out_p(). Look up in Linux. Now, so that
built in function of glibc don't confuse us, we cancel them

#undef memcpy

set some of our own functions:

static void puts(const char *);

static char vidmem =(char)0xb8000;
/*video memory address*/

static int vidport; /*videoport*/

static int lines,cols; /* number of lines and colors on a screen*/

static int curr_x,curr_y; /*current cursor position*/

Now, we will start program in a normal (high level) language with some more assembly of course:).

The function ov moving cursor into (x,y). The is done via I/O into videoport.

 void gotoxy(int x, int y)
 {
     int pos;
     pos=(x+cols*y)*2
     outb_p(14,vidport);
     outb_p(0xff & (pos>>9),vidport+1);
     outb_p(15,vidport);
     outb_p(0xff &(pos>>1),vidport+1);
 }
 
 Screen scrolling function. Works using direct writing into video memory.
 
 static void puts(const char*s)
 {
     int x,y;
     char c;
     x=curr_x;
     y=curr_y
     while((c=*s++)!=``){
         if(c==``){
             x=0;
             f(++y>=lines){
             scroll();
             y--;
             }
         }
     else{
         vidmem[(x+cols*y)*2]=c;
         if(++x>=cols){
                     x=0;
                     if(++y>=lines){
                                 scroll();
                                 y--;
                             }
                         }
                     }
                 }
             gotoxy(x,y);
         }
 
 
 
 Function copy from one part of memory to another.
 
 Void* memcpy( void*__dest,__const void*___src,unsigned int__n)
 {
     int I;
     char*d=(char*)dest,*s=(char*)__src;
     for(I=o;I<__n,I++) d[i] =s[i]
 }
 
 Function, making long nice. Very usefull for debugging.
 
 Make_sound()
 {
     __asm__("
     movb $0xB6, %al
     outb %al,$0x43
     movb $0x0D, %al
     outb %al,$0x43
     movb $0x11,%al
     outb %al,$0x42
     inb $0x61,%al
     orb $3,%al
     outb %al,
     outb %al,$0x61
 ");
 }
 And here is the main function.
 
 Int start_my_kernel()
 {
 /*setting general parameters*/
     vidmem=(char*)0xb8000;
     vidport=0x3b4;
     lines=25;
     cots=80;
 /* reading the saved cursor coordinates*/
 
 curr_x=*(unsigned char *)(0x8000);
 curr_y=*(unsigned char *)(0x80001);
 
 /*show the following*/
 
 puts("MiniOS Loaded/n");
 /*Go into endless loop*/
 
 while(1);
 }
 

This is the end of your experience. Now you have your own OS.



This article was originally written by ivi

Did you like this article? There are hundreds more.

Comments:
aton
2004-03-27 11:11:46
dude you rock! i tried to switch to protected mode for sooo long and never could manage to do so... very nice article
Anonymous
2005-12-17 05:01:06
Master your great!!!
Anonymous
2006-06-09 06:38:57
All I can say is, Wow, and Thanks!
Anonymous
2007-10-27 13:04:17
i dunno any programmin..but this will be it..i try it tonight!
Anonymous
2007-12-24 21:50:45
I have a half of an operating system created by me but I used a bootsector image that I downloaded from the net. This was the first one I could assemble myself.

Thank You :-D
Anonymous
2008-01-03 13:29:50
what programming software do you need to do this? This is the problem I have.
and..... how do you boot it?
Anonymous
2008-04-02 18:54:54
Thats quite interesting.

Thanks
Online Yellow Pages
Canadian Yellow Pages
Plumbers Directory
Dreamhost coupon
Anonymous
2008-08-15 16:07:01
?I am not a genius but.. I don't understand anything about it?!?

(sorry type faults, I am dutch)
Anonymous
2009-03-18 00:33:03
Hey i make soe crazy stuff that amazes everyone on my computer but i can't get this. What programs do you pu these codes into, notepad?
Anonymous
2009-09-21 06:20:44
Thanks for the article

Dreamhost coupon
Anonymous
2009-09-21 06:51:56
Great read!

Dreamhost promo code
Anonymous
2009-10-07 14:23:53
Respectable Reviews
Fat Loss 4 Idiots Review
The Tweet Tank Review
Dog Food Secrets Review
Acne Free In 3 Days Review
Singorama Review
Forex Apocalypse Review
The Scar Solution Review
My Airfare Secrets Review
Acne No More Review
Lose The Back Pain Review
Anonymously add a comment: (or register here)
(registration is really fast and we send you no spam)
BB Code is enabled.
Captcha Number:


Blogs: (People who have posted blogs on this subject..)
jackier
jackier on Mon 13th Oct 10am
111
sefo
Sneak - encryption on Fri 17th Nov 12pm
I'm developing the win32 version of sneak: http://snarkles.net/scripts/sneak/sneak. php The ASM source code is available on cyberarmy svn (for members only - free) Check the forum for details: http://www.cyberarmy.net/forum/sneak/mes sages/295244.
sefo
Geek Toolbar on Mon 13th Nov 8am
This a very simple and small toolbar I wrote in my spare time. I use the same set of tools very often and I find it very annoying to look for them in the start menu, on the desktop or in explorer. http://www.osix.net/modules/folder/index .php?tid=134
sefo
BinScan and Alternate Data Stream on Thu 27th Jul 9am
BinScan I created this tool to quickly identify modifications in the PE, use of a TLS callback and Alternate Data Streams. -> Some modifications done in the PE structure of an executable can prevent debuggers or other tools to open the executable.
sefo
Wmf Creator on Wed 26th Jul 7am
Now that the blog is online, I'll be able to share two or three tools I wrote. The first one I'd like to share is WMF Creator. I already put a link in the comments of my article: Wmf Exploit but I thought it would look nicer here. This tool will tak

Test Yourself: (why not try testing your skill on this subject? Clicking the link will start the test.)
Reverse Engineering by Geek_Freek

A test to check your assembly and reversing skills.
Assembly Language - non compiler specific by TroPe

You can test your assembly knowledge by taking this test. It starts out relatively easy, but gets progressively hards very quickly! If you know assembly, or just want to see what you DONT know about assembly, this test is for you. A more advanced assembly

Related Links:
ASM 104
ASM 103
ASM 102
ASM 101
Storing data to discontinuous strings
[român?] x86 Assembly Language pentru incepatori - Partea 1
[Deutsch] x86 Assembler für Anfänger - Teil 1
[Deutsch] Assembler Teil 1
Adding a function to win32 SNEAK :: translation table (xlat)
Scanning for Alternative Data Streams
Yaz?l?m Koruma Teknikleri
[Bahasa Indonesia] OSIX MEMPERSEMBAHKAN: Membalikkan Malware I and II
OSIX PRESENTS: Reversing Malware I and II


     
Your Ad Here
 
Copyright Open Source Institute, 2006