You are on page 1of 15

Building your own operating system - CodeProject

http://www.codeproject.com/KB/system/MakingOS.aspx

Not quite what you are looking for? You may want to try: Clean and quick cancellation of I/O operations A Practical Approach to Computer Systems Design and Architecture
7,682,156 members and growing! (28,124 online) Email Password Sign in Join Remember me? Lost password? highlights off

Home

Articles Help!

Questions & Answers The Lounge

Learning Zones

Features

how to create OPERATING SYSTEM

General Reading Hardware & System General Licence First Posted Views Downloads Bookmarked CPOL 6 Oct 2006 215,867 2,542 298 times

See Also
More like this More by this author

By S Keller | 11 Oct 2006


C++ C Windows Visual-Studio Dev ASM Intermediate

Writing your own operating system. Prize winner in Competition "MFC/C++ Sep 2006"
102

Article Browse Code Stats Revisions


4.78 (181 votes)

Sponsored Links

Download project files - 4.51 Kb Download BOOT sector utility - 41.4 Kb

See Also...

1 of 15

4/5/2011 4:47 AM

Building your own operating system - CodeProject

http://www.codeproject.com/KB/system/MakingOS.aspx

Cosmos - C# Open Source Managed Operating System Build your own OS in Visual Studio and C#. How to develop your own Boot Loader This article describes the first steps in... Beginning Operating System Development, Part One Introduction and environment setup Develop Your Own Operating System in C# or VB.NET Develop your own operating system using C# (or...

The Daily Insider


30 free programming books Daily News: Signup now.

Introduction
If you know how an operating system works, it will help you a lot in programming, especially for system programs like device drivers; even for non-system-programming, it can help a lot. And also, I'm sure every one would like to have their own operating system. You would also learn from this article how to read and write raw sectors from a disk.

Background
In this article, I would explain the first part of building an operating system. Here is what happens when you start your computer: 1. The BIOS (Basic Input Output System this is a program that comes with any mother board and it is placed in a chip on the mother board) checks all the computer components to make sure that they are all working. 2. If all the components are working, the BIOS starts searching for a drive that might have an operating system. (The BIOS can look in hard drives, floppy drives, CD-ROM drives etc. The order the BIOS checks can be set it in the BIOS setup program. To get to the BIOS setup, right when the computer turns on, press the DELETE key until you see the BIOS setup program; in some computers, it can be a different button than DELETE, so look in your mother board specification to find how to get to the BIOS setup program. And also look up (if you dont now how to do it) how to change the search search of BIOS while looking for an operating system.) 3. The BIOS checks the first drive to see if he has a valid BOOT sector. (A disk is divided into little regions that are named sectors. The BOOT sector size is 512 bytes in most drives.) If the drive has a valid BOOT sector, the BIOS loads that sector in to the memory at address 0:7c00 (=31,744) and gives control to that area of the memory.

2 of 15

4/5/2011 4:47 AM

Building your own operating system - CodeProject

http://www.codeproject.com/KB/system/MakingOS.aspx

4. Now this little program that was loaded from the BOOT sector continues to load the operating system, and after the operating system is loaded, it initializes the operating system and gives the control to the operating system.

Making a bootable disk


The steps would be like this: 1. Take a floppy diskette that you don't need. 2. Use the program that comes with this article, BOOTSectorUtility.exe, to copy the file BOOT.bin to the floppy diskette BOOT sector. 3. Make sure that your BIOS is set to BOOT from the floppy drive first, so that our operating system would be loaded. 4. Restart your computer (make sure that the floppy diskette is in the drive), and watch what our BOOT sector does. With BOOTSectorUtility.exe, you can also search your regular operating system, by saving the boot sector of the drive of your operating system to a file. And to read that file, start the command line and type Debug <file path> (if you have a Microsoft operating system). The Debug command starts a 16 bit debugger (any boot sector is in 16 bit code, because when the computer starts, it is in 16 bit mode, and only after the boot sector is run, can it change the CPU to 32 bit mode or 64 bit mode). Press u <Enter> (u = unassemble) to unassemble the file. Figure 1 shows an example. Figure 1 Unassembeling 16 bit code.

Reading raw bytes from a drive


You can read raw sectors from a drive like this:
Collapse

//

3 of 15

4/5/2011 4:47 AM

Building your own operating system - CodeProject

http://www.codeproject.com/KB/system/MakingOS.aspx

// Reading/writing raw sectors. //

//pBuffer has to be at least 512 bytes wide. BOOL ReadSector(char chDriveName,char *pBuffer,DWORD nSector) { char Buffer[256]; HANDLE hDevice; DWORD dwBytesReaden; //Init the drive name (as a Driver name). sprintf(Buffer,"\\\\.\\%c:",chDriveName); hDevice = CreateFile(Buffer,

// drive to open.

GENERIC_READ, FILE_SHARE_READ | // share mode. FILE_SHARE_WRITE, NULL, // default security attributes. OPEN_EXISTING, 0, NULL); // disposition. // file attributes. //

if(hDrive==INVALID_HANDLE_VALUE)//if Error Openning a drive. { return FALSE; } //Move the read pointer to the right sector. if(SetFilePointer(hDevice, nSector*512, NULL, FILE_BEGIN)==0xFFFFFFFF) return FALSE; //Read the Sector. ReadFile(hDevice, pBuffer, 512, &dwBytesReaden, 0); //if Error reading the sector. if(dwBytesReaden!=512) return FALSE; return TRUE; }

Making a BOOT program


Now, I will explain the basics of a boot program (to understand this,

4 of 15

4/5/2011 4:47 AM

Building your own operating system - CodeProject

http://www.codeproject.com/KB/system/MakingOS.aspx

you need to be familiar with Assembler and Interrupts and Interrupts vector table). [Interrupts vector table = From Address 0 -> 1,024 holds 256 structures (4 bytes in size) that holds an address in the form: CS:IP = xxxx:xxxx. So you have addresses from INT 1 -> INT 256. Each interrupt has an index into that table. This table is used like this: if you, for example, use the instruction INT 10h, the CPU checks in index 10h in the interrupt table were the address of the routine is that handles INT 10h, and the CPU jumps to that address to execute it]. Now, I will explain how to print a string, read sectors, and wait for a key press using only the BIOS. To print a string, I use the INT 10h function 0Ah (AH = 0Ah). To move the cursor, I use the INT 10h function 2h (AH = 2h). To read sectors, I use the INT 13h function 2h (AH = 2h). To wait for a key stroke, use the INT 16h function 0h (AH = 0h). I used TASM v3.1 and TLINK to make my boot sector, but you can use any x86 16 bit assembler compiler. (If you can't get a copy of TASM and TLINK, you can send me an e-mail and if it is legal, I would send you a copy of them). (TASM and TLINK v3.1 were released in 1992 by Borland International). Now I would explain the steps the BOOT program does. 1. Make a stack frame (if not you don't have any stack). 2. Set the DS (data segment) so you can access the data. 3. In my boot sector, I added this: (Display a message to the user, Wait for a key stroke, Continue). 4. Set up the Disk Parameter Block (the Disk Parameter Block is a structure that holds information about the drive, like how much sectors it has etc., the drive controller uses it for knowing how to read the disk in the drive). 5. To set the Disk Parameter Block, get its address (its address is pointed by INT 1Eh (in the memory, this is 1E x 4 bytes = 78h = 30 x 4 bytes = 120). This is an example of how to initialize the Disk Parameter Block for a 3.5 inch (1.44 MB) floppy Disk.
Collapse

StepRateAndHeadUnloadTime 0DFh HeadLoadTimeAndDMAModeFlag DelayForMotorTurnOff 25h BytesPerSector 2h SectorsPerTrack 12h IntersectorGapLength 1bh DataLength 0FFh IntersectorGapLengthDuringFormat 54h

db db db db db db db db 2h

5 of 15

4/5/2011 4:47 AM

Building your own operating system - CodeProject

http://www.codeproject.com/KB/system/MakingOS.aspx

FormatByteValue 0F6h HeadSettlingTime 0Fh DelayUntilMotorAtNormalSpeed

db db db 8h 0 0 0

DisketteSectorAddress(as LBA)OfTheDataArea db CylinderNumberToReadFrom db SectorNumberToReadFrom db DisketteSectorAddress (as LBA) OfTheRootDirectory db 0

6. And set the address that INT 1E points at to the address of the Disk Parameter Block you set up. 7. Reset the drive (by using the INT 13h function 0). 8. Start reading the diskette by using the INT 13h function 2h. 9. Give control to the loaded operating system (this is done by inserting in the code the op code of a jump to were you loaded the operating system. Let's say you loaded the operating system 512 bytes from were the BIOS loaded the BOOT sector (0:7c00h).
Collapse

db 0E9h db 512

; FAR JMP op code. ; 512 bytes

or you can use another way: call some address, and there, change the return address in the stack to were you want the jump to, like this:
Collapse

call GiveControlToOS GiveControlToOS: Pop ax Pop ax Mov ax,CodeSegement to return. Push ax mov ax,InstructionPointer to return. Push ax ret modified address. ;Return to the

;Push the new CS

;Push the new IP

10. In the end of the boot sector the bytes would be 0x55h 0x0AAh. If the boot sector doesnt have this value, the BIOS would not load that boot sector. After this, the BOOT sector finishes its job and the operating system starts running. You can download the files I used for my boot sector here, the files are BOOT.asm, BOOT.bin (this is the sector itself).

The BOOT sector program


Collapse

.MODEL SMALL

6 of 15

4/5/2011 4:47 AM

Building your own operating system - CodeProject

http://www.codeproject.com/KB/system/MakingOS.aspx

.CODE ORG 7c00h ;Because BIOS loades the OS at ; address 0:7C00h so ORG 7C00h ; makes that the refrence to date ; are with the right offset (7c00h).

ProgramStart:

; CS = 0 / IP = 7C00h // SS = ? / SP = ? ; You are now at address 7c00. jmp start ;Here we start the, BIOS gave us now the control.

;/////////////////////////////////////////// ;//Here goes all the data of the program. ;///////////////////////////////////////////

xCursor db 0 yCursor db 0

nSector nTrack nSide nDrive nTrays

db db db db

0 0 0 0

db 0

'Are You Ready to start Loading the OS...',0 szReady db 'Error Reading Drive, Press any Key to reboot...',0 szErrorReadingDrive db ;//Done Reading a track. szPlaceMarker szDone db db '~~~~',0 'Done',0

pOS dw 7E00h ;//Points to were to download the Operating System.

;//Disk Paremeter Table. StepRateAndHeadUnloadTime HeadLoadTimeAndDMAModeFlag DelayForMotorTurnOff ;// (1 = 256) //(2 = 512 bytes) BytesPerSector ;// 18 sectors in a track. SectorsPerTrack IntersectorGapLength DataLength IntersectorGapLengthDuringFormat FormatByteValue HeadSettlingTime db db db 0DFh 2h 25h

db

2h

db db db db db db

18 1Bh 0FFh 54h 0F6h 0Fh

7 of 15

4/5/2011 4:47 AM

Building your own operating system - CodeProject

http://www.codeproject.com/KB/system/MakingOS.aspx

DelayUntilMotorAtNormalSpeed

db

8h 0 0 0 db

DisketteSectorAddress_as_LBA_OfTheDataArea db CylinderNumberToReadFrom db SectorNumberToReadFrom db DisketteSectorAddress_as_LBA_OfTheRootDirectory ;///////////////////////////////// ;//Here the program starts. ;/////////////////////////////////

Start: CLI ;Clear Interupt Flag so while setting ;up the stack any intrupt would not be fired.

mov AX,7B0h 7c00h-256 = 7B00h mov SS,ax mov SP,256

;lets have the stack start at

;SS:SP = 7B0h:256 = 7B00h:256 ;Lets make the stack 256 bytes.

Mov ax,CS mov DS,ax XOR AX,AX MOV ES,AX

;Set the data segment = CS = 0

;Makes AX=0. ;Make ES=0

STI

;Set Back the Interupt Flag after ;we finished setting a stack fram.

Call ClearScreen LEA AX,szReady CALL PrintMessage CALL GetKey

;ClearScreen() ;Get Address of szReady. ;Call PrintfMessage() ;Call GetKey()

CALL SetNewDisketteParameterTable ;SetNewDisketteParameterTable()

CALL DownloadOS CALL GetKey CALL FAR PTR GiveControlToOS

;Call GetKey() ;Give Control To OS.

ret ;///////////////////////////////////// ;//Prints a message to the screen. ;/////////////////////////////////////

8 of 15

4/5/2011 4:47 AM

Building your own operating system - CodeProject

http://www.codeproject.com/KB/system/MakingOS.aspx

PrintMessage PROC mov DI,AX Display. Mov xCursor,1 ;Column. ;AX holds the address of the string to

ContinuPrinting: cmp byte ptr [DI],0 String. JE EndPrintingMessage string return. ;if you gat to the end of the ;Did we get to the End of

mov AH,2 mov DH,yCursor mov DL,xCursor mov BH,0 INT 10h INC xCursor mov AH,0Ah mov AL,[DI] mov BH,0 mov CX,1 character INT 10h

;Move Cursor ;row. ;column. ;page number.

;Display Character Function. ;character to display. ;page number. ;number of times to write

INC DI

;Go to next character.

JMP ContinuPrinting

;go to Print Next Character.

EndPrintingMessage: Inc yCursor ;So Next time the message would ;be printed in the second line.

cmp yCursor,25 JNE dontMoveCorsurToBegin Mov yCursor,0 dontMoveCorsurToBegin: ret

PrintMessage EndP ;////////////////////////////////////// ;//Watis for the user to press a key. ;////////////////////////////////////// GetKey PROC

9 of 15

4/5/2011 4:47 AM

Building your own operating system - CodeProject

http://www.codeproject.com/KB/system/MakingOS.aspx

mov ah,0 int 16h ;Wait for a key press. Ret GetKey EndP ;/////////////////////////////////////////// ;//Gives Control To Second Part Loader. ;/////////////////////////////////////////// GiveControlToOS PROC LEA AX,szDone Call PrintMessage CALL GetKey db 0e9h dw 512 ;Far JMP op code. ;JMP 512 bytes ahead.

POP AX

;//Another why to make ;the CPU jump to a new place.

; ; ;

POP AX Push 7E0h Push 0 ;Push New CS address. ;Push New IP address. ;The address that comes out is 7E00:0000. ;(512 bytes Higher from were BIOS Put us.)

ret

GiveControlToOS EndP ;/////////////////////////////////// ;//Clear Screen. ;/////////////////////////////////// ClearScreen PROC mov ax,0600h Screen. mov mov mov int bh,07 cx,0 dx,184fh 10h ;//Set Corsur Position So next //write would start in //the beginning of screen. Mov yCursor,0 Ret ClearScreen EndP ;///////////////////////////////// ;//PrintPlaceMarker. ;//Scroll All Screen UP to Clear

Mov xCursor,0

10 of 15

4/5/2011 4:47 AM

Building your own operating system - CodeProject

http://www.codeproject.com/KB/system/MakingOS.aspx

;///////////////////////////////// PrintPlaceMarker PROC

LEA AX,szPlaceMarker CALL PrintMessage ;Call PrintfMessage() CALL GetKey ret PrintPlaceMarker EndP ;///////////////////////////////////////// ;//Set New Disk Parameter Table ;///////////////////////////////////////// SetNewDisketteParameterTable PROC LEA DX,StepRateAndHeadUnloadTime ;//Get the address of the Disk Parameters Block. ;Call GetKey()

;//Int 1E (that is in address 0:78h) ;//holds the address of the disk parametrs ;//block, so now change it to ;//our parametr black. ;//DX holds the address of our Parameters block. MOV WORD PTR CS:[0078h],DX MOV WORD PTR CS:[007Ah],0000 ;Reset Drive To Update the DisketteParameterTable. MOV AH,0 INT 13H ret SetNewDisketteParameterTable EndP ;/////////////////////////////////// ;//DownloadOS ;/////////////////////////////////// DownloadOS PROC mov mov mov mov nDrive,0 nSide,0 nTrack,0 nSector,1

ContinueDownload: INC nSector cmp nSector,19 JNE StayInTrack CALL PrintPlaceMarker would ;now that we finished reding a ;Read Next Sector. ;Did we get to end of track.

;Print now '~~~~' so the user

11 of 15

4/5/2011 4:47 AM

Building your own operating system - CodeProject

http://www.codeproject.com/KB/system/MakingOS.aspx

track INC nTrack Move to next track. mov nSector,1 CMP nTrack,5 value ;to how much Tracks you want to read). JE StayInTrack: ;ReadSector(); Call ReadSector EndDownloadingOS ;If we gat to end of track

;And Read Next Sector. ;Read 5 Tracks (Modify this

JMP ContinueDownload ;If diden't yet finish Loading OS.

EndDownloadingOS: ret DownloadOS EndP ;//////////////////////////////////////// ;//Read Sector. ;//////////////////////////////////////// ReadSector PROC mov nTrays,0 TryAgain: mov AH,2 mov AL,1 mov CH,nTrack mov CL,nSector with 1, not 0. mov DH,nSide mov DL,nDrive Mov BX,pOS ;//Read Function. ;//1 Sector.

;//Remember: Sectors start

;//ES:BX points to the address ;to were to store the sector.

INT 13h

CMP AH,0 JE EndReadSector function.

;Int 13 return Code is in AH. ;if 'Sucsess' (AH = 0) End

mov AH,0 Again... INT 13h cmp nTrays,3

;Else Reset Drive . And Try

;Chack if you tryed reading

12 of 15

4/5/2011 4:47 AM

Building your own operating system - CodeProject

http://www.codeproject.com/KB/system/MakingOS.aspx

;more then 3 times.

JE DisplayError Error.

; if tryed 3 Times Display

INC nTrays jmp TryAgain ;Try Reading again.

DisplayError: LEA AX,szErrorReadingDrive Call PrintMessage Call GetKey mov AH,0 INT 19h

;Reboot Computer.

EndReadSector: ;ADD WORD PTR pOS,512

;//Move the pointer ;(ES:BX = ES:pOS = 0:pOS) 512

bytes. ;//Here you set the varible ;pOS (pOS points to were BIOS ;//Would load the Next Sector). Ret ReadSector EndP ;//////////////////////////////////// ;// ;//////////////////////////////////// END ProgramStart

Points of interest
It took some time until I got a running boot sector. I would list a couple of bugs I had in the beginning while writing my boot sector. 1. I didnt set up a right stack frame. 2. I didnt modify the Disk Parameter Block. 3. I loaded the operating system to areas that are used by BIOS routines (and even to the Interpret table). 4. In the end of the boot sector, it must have the bytes 0x55h 0x0AAh (this is a signature that it is a valid bootable sector). (For using BOOTSectorUtility.exe, you would need the .NET 2.0 Framework installed on your computer. To download the .NET 2.0 Framework, click here.) If I see that this article interests people, I would write some more articles on this subject.

License

13 of 15

4/5/2011 4:47 AM

Building your own operating system - CodeProject

http://www.codeproject.com/KB/system/MakingOS.aspx

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

About the Author


S Keller
Systems Engineer United States Member Sign Up to vote for this article

Article Top

Comments and Discussions


You must Sign In to use this message board. (secure sign-in) FAQ Noise Tolerance
Medium

Search Layout
Normal

Per page

25

Update

Msgs 1 to 25 of 102 (Total in Forum: 102) (Refresh) My vote of 5 My vote of 5 Suppose If User try it In His Local Drive DiskParameterBlock(DPB) view the dump DPB details information BOOTSectorUtility.exe hi The Tasm and Tlink? Re: The Tasm and Tlink? Hi! tuan_chaos@yahoo.com.vn Operating System MY OPERATING SYSTEM. Re: MY OPERATING SYSTEM. Hi Re: Hi Problem with "BOOTSectorUtility" Boot sector saxena durgesh cameleon_fr ShariqDON Shanay Shanay Shanay taheri Colin Geek Bright Mazura Carllbrando23 tuan1111 Gogeta_ulti Dilip Jamkhandi Tirtesh soft_man Carllbrando23 JimB121 non-bugging Errors

First Prev Next 21:18 14 Dec '10 7:35 16 Sep '10 12:19 1 May '10 23:21 29 Apr '10 21:45 29 Apr '10 21:35 29 Apr '10 2:51 21 Dec '09 18:47 6 Nov '09 23:38 7 Oct '09 16:58 15 Mar '10 19:04 12 May '09

21:55 1 May '09 6:52 16 Apr '09 2:25 26 Aug '09 1:30 4 Feb '09 16:59 15 Mar '10 18:53 23 Dec '08 20:22 17 Dec '08

14 of 15

4/5/2011 4:47 AM

Building your own operating system - CodeProject

http://www.codeproject.com/KB/system/MakingOS.aspx

New article... Re: New article... Re: New article... Re: New article... help Re: help Re: help Last Visit: 19:00 31 Dec '99 General Admin News

Jaeman S Keller Jaeman S Keller muncheez123 S Keller muncheez123 Last Update: 0:50 5 Apr '11 Question Answer Joke

13:11 13 Jun '08 18:26 5 Aug '08 22:27 6 Aug '08 1:42 11 Aug '08 19:30 7 Jun '08 18:24 5 Aug '08 11:56 31 Jan '09 1 2 3 4 5 Next Rant

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+PgUp/PgDown to switch pages.
link | Privacy | Terms of Use | Mobile Last Updated: 11 Oct 2006 Copyright 2006 by S Keller Everything else Copyright CodeProject, 1999-2011 Web24 | Advertise on the Code Project

15 of 15

4/5/2011 4:47 AM

You might also like