Building Your Own Operating System - Code Project
Building Your Own Operating System - Code Project
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!
Learning Zones
Features
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
Writing your own operating system. Prize winner in Competition "MFC/C++ Sep 2006"
102
Sponsored Links
See Also...
1 of 15
4/5/2011 4:47 AM
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...
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
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.
//
3 of 15
4/5/2011 4:47 AM
http://www.codeproject.com/KB/system/MakingOS.aspx
//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; }
4 of 15
4/5/2011 4:47 AM
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
http://www.codeproject.com/KB/system/MakingOS.aspx
db db db 8h 0 0 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
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
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).
.MODEL SMALL
6 of 15
4/5/2011 4:47 AM
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.
xCursor db 0 yCursor db 0
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
;//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
7 of 15
4/5/2011 4:47 AM
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.
STI
;Set Back the Interupt Flag after ;we finished setting a stack fram.
8 of 15
4/5/2011 4:47 AM
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
;Display Character Function. ;character to display. ;page number. ;number of times to write
INC DI
JMP ContinuPrinting
EndPrintingMessage: Inc yCursor ;So Next time the message would ;be printed in the second line.
PrintMessage EndP ;////////////////////////////////////// ;//Watis for the user to press a key. ;////////////////////////////////////// GetKey PROC
9 of 15
4/5/2011 4:47 AM
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
; ; ;
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
http://www.codeproject.com/KB/system/MakingOS.aspx
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.
11 of 15
4/5/2011 4:47 AM
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
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.
INT 13h
12 of 15
4/5/2011 4:47 AM
http://www.codeproject.com/KB/system/MakingOS.aspx
JE DisplayError Error.
DisplayError: LEA AX,szErrorReadingDrive Call PrintMessage Call GetKey mov AH,0 INT 19h
;Reboot Computer.
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
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)
Article Top
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
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