|kinggkong||Date: Thursday, 2011-12-29, 6:01 PM | Message # 1|
1. Introduction 3
2. Applications 4
3. Boot process 5
4. Interrupts 6
5. Creating the Loader 7
6. Building the Kernel 9
7. Writing and Testing 11
8. Final Thoughts 13
In this tutorial, I will teach the basic steps to create a mini operating system
X86 16-bit, fully programmed from scratch in assembly. I will not teach
nothing about the programming language itself, so it is recommended to have some knowledge about it.
Let's do something really basic, but enough for you to understand how the
operation of an OS. We will just be a text message displayed on
screen. It seems little, but you will see that the thing is not so simple.
See the required applications in the next chapter and good luck.
To program the system, we use the Emu8086, a great emulator for 8086, with
ability to compile, debugging, and of course to emulate the system (not to have to stay
restarting the computer every hour to test).
Emu086: (to download go to the bottom of the page.)
VirusScan: !!!emu8086v408r.exe - Verificador de malware do Jotti
He is not free, has a period of 90 days to test, but is sufficient for our
tutorial. Then download two more applications that we use to our record in SO to a floppy and boot it:
Fergo RawImage Maker: Fergonez.net - Download File
VirusScan: FergoRaw.exe - Verificador de malware do Jotti
RawWriteWin:chrysocome.net - RawWrite for Windows
VirusScan: rawwritewin.exe - Verificador de malware do Jotti
The place of installation of these applications is their choice, not have a specific location
to install. Let's move on to a brief explanation of the boot process.
3. PROCESSO DE BOOT
Generally, after the hardware check, the computer search for
512 bytes written in the first sector of the diskette (Head: 0, Track 0, Sector 1). case
not find it search for an operating system in the MBR (Master Boot Record) of the
your hard drive.
It is important to test the OS, you configure the BIOS to "boot" floppy
before any other device (HDD, CDROM, USB, etc ...).
If it finds those 512 bytes of system disk, he carries on
memory at address 0000:7 C00h. Let's see how these addresses
When using the format xxxx: yyyy, you are working with relative addresses,
with the first sequence represents what we call Segment and the second
Offset. To calculate the physical address, real, the following calculation is done (remember that
we are working with hexadecimal numbers, indicated by 'h' after the last
Segment * 16h + Offset = physical address
Taking as an example where the BIOS loads the operating system, we can calculate the actual physical address by calculating:
[COLOR="rgb(65, 105, 225)"] 0000h * 16h + 7C00h = 7C00h [/COLOR]
How important to know about these addresses? Well, it's for them that you will control their program. You can use physical addresses directly, but using
in the form of segment / offset you can better organize the positions of
The physical address is also important to know where I can and where I do not I can write data into memory. The BIOS reserves a stretch of low memory (640KB) for you to use it freely. This excerpt is from physical address 00500h to A0000h. That is, you should not write anything before or after and address 00500h or after A0000 (places are reserved for video memory, BIOS, interrupt vectors (see below), etc ... ).
Returning to boot. Did I mention that it loads the first sector of 512 bytes in
memory. Okay, what if my OS has more than 512 bytes? Then we will need a
Loader, which is basically a sequence of instructions (with a maximum of 512 bytes to fit in the first sector), which is responsible for loading the kernel from disk to memory. Let's use one for our OS (although you do not need in this case).
I said in the introduction that would not explain about assembly language, but I think Interrupts is something important to highlight.
Interrupt, if the Assembly is an instruction that halts the current code so that some action is performed (we call this IRQ - Interruption Request). If it is something to compare with the high-level languages, we can compare it with a
function, which is called, executes its instructions, and then returns to the code where it was called.
Every computer on the x86 architecture has several interrupts controlled by the BIOS.
The interrupts are composed of a function and subfunction. For example, to work with video, we use interrupt 10h. And the operation to be performed in the video (subfunction), depends on the value of some register (usually AH). See the example below which prints a character on the screen:
mov ah, 0Eh ;subfunção que indica para imprimir texto
mov al, ‘A’ ;caractere a ser impresso
int 10h ;interrupção de vídeo
How do I know what each interrupt it? What are the arguments and which registers are involved? I use this site:
Interrupt Services DOS, BIOS, EMS und Mouse
Let's use Interrupts to print characters on the screen, to check for key presses to change the video mode, etc.. Can you see to understand its functioning is essential to proceed with this tutorial.
Let's put our hands dirty now.
5. CRIANDO O LOADER
The Loader is basically a set of instructions that must fit in the first sector of the diskette (512b) and reading the other sectors of the disk (where the kernel and the rest of the code) into memory.
Our code needs to set some basic things so that everything works correctly. We must have a data stack (Stack). If you program in assembly, ought to know what a cell is, how it works, and what it is used.
The registers involved in the stack are:
SS -> Stack Segment -> points to the segment where the SP Stack -> Stack Pointer -> Points to a given region of the cell (usually the top)
In addition to the stack, it is necessary to indicate where our data segment DS -> Data Segment -> Points to the database (used whenever you access any memory address).
We organize our memory as follows:
07C0:0000 até 07C0:01FF Where it was loaded the bootloader
07C0:0200 até 07C0:03FF Stack
0800:0000 On Our Kernel
This structure of memory is the same used in Emu8086 site, it is very didactic and follows a logical sequence. Of course it will be left a good stretch (from 0500 to 7C00), but for now suffice.
So here is the sequence that we use in our Loader
• Determines the stack and its registers
• Indicates the data segment
• Changes the video format to 80x25 (80 columns, 25 lines)
• Read the section of the disk where the kernel
• Write the read data at address 0800:0000
• Skips to this address and passes control to the kernel
Open Emu8086, select 'New' and check 'Empty Workspace'. Then paste the code on the next page (I'll make comments about what makes each statement in the code itself)
org 7C00h ;organizes the offset
mov ax, 07C0h
mov ss, ax ;sets the SS to 07C0h
mov sp, 03FEh ;points to the top of the stack
;arrow data segment
xor ax, ax ;resets AX
mov ds, ax ;sets the data segment 0000h
;change the video mode
mov ah, 00h ;subfucao to set video mode
mov al, 03h ;03h = 80x25, 16 colors
int 10h ;interrupt the video
;reads data from the floppy
mov ah, 02h ;subfunction reading
mov al, 1 ;number of sectors to read
mov ch, 0 ;trail ( cylinder )
mov cl, 2 ;sector
mov dh, 0 ;Head
mov dl, 0 ;drive ( 00h = A: )
mov bx, 0800h ;ES:BX points to the memory location_
mov es, bx ;where the data will be written_
mov bx, 0 ;0800:0000h ( ES = 0800h, BX = 0000h )
int 13h ;floppy interrupt
jmp 0800h:0000h ;jumps to the location of the kernel
;and passes execution to it
The number of sectors to be read varies with the size of the kernel. Each sector is 512 bytes. So if the kernel has 512 bytes or less, just read a sector. If you have 700 bytes, need to read two sectors and so on.
If you have questions about the values, go to the site with the list of interrupts and I stated that the review concerned Int.
Save and compile this code using the button 'compile' on the toolbar. He will ask you where you want to save the file (which will have the extension. Bin). Give any name (something like loader.bin) and save in the directory you want.
6. CRIANDO O KERNEL
Our kernel is going to be as simple as possible. It will just write a text on the screen and wait for the user to press any key to restart the computer. It may seem small but is enough for you to understand how a basic system works. If you need something else do the kernel (of course you'll want to), you will have already
sufficient knowledge to be able to use other interrupts, and work better with memory, etc..
org 0000h ;organizes the offset
push cs ;CS = address of the current program
pop ds ;DS = CS
call clearscreen ;called procedure to clean the screen
lea si, Message ;SI = address of the message
mov ah, 0Eh ;subfunction to print character
mov al, [si] ;moves to AL the character in SI
cmp al, 0h ;compared to 0 (end of string)
jz ended ;If finished, skip to 'terminated'
int 10h ;interruption of video
inc si ;next character
jmp repetition ;repeats the process until you find the 0
mov ah, 0h ;subfunction to wait for key
int 16h ;keyboard interrupt
mov ax, 0040h ;reboot method is to set_
mov ds, ax ;the value of the address 0040:0072 h_
mov w.[0072h], 1234h ;to 1234h and jump to the endereço_
jmp 0FFFFh:0000h ;FFFF:0000h
clearscreen proc ;procedure to clear the screen
pusha ;puts all reg on the stack
mov ah, 06h ;subfunction to scroll upwards
mov al, 0 ;clears the screen
mov bh, 0000_1111b ;arrow colors ( background_text )
mov ch, 0 ;corner of the online sup. esq.
mov cl, 0 ;the corner column sup. esq.
mov dh, 19h ;online singing inf. dir. (25)
mov dl, 50h ;corner column. inf. dir. ( 80 )
int 10h ;video interrupt
popa ;restores the register values
ret ;returns to the code
Message db "My First OS ', 0, and our string that will be displayed
Again, if in any doubt as to that code (which is not on the syntax and commands of the Assembly), return to the site with the list of interrupts.
Once done, save the file and compile the same way as did the Loader.
Of course, choose another name (perhaps kernel.bin). Try to keep the files in one folder, to keep organized.
Our mini operating system is ready. The only thing missing records it on the floppy and test.
7. RECORDING AND TESTING
With the binary loader and kernel in hand, let's create an image to be recorded on the diskette. Let's use a tool that I programmed called Fergo RawImage Maker.
OBS.: If you need, download the VB6 Runtime Libraries.
Run the program. The interface is simple and intuitive. Follow these steps to create the image (numbers in parentheses are related to the image).
• Choose the target file (1)
• Select the loader.bin in the second text box (2)
• Mark = Head 0, Cylinder and Sector = 0 = 1 (3)
• Click Add (4)
• Select the kernel.bin in the second text box (2)
• Mark = Head 0, Cylinder and Sector = 0 = 2 (3)
• Click Add (4)
• And then click 'Create File!' (5)
Pay special attention to sectors that you are recording. Make sure the end result was similar to the image list.
If all went well, must have appeared a message that the file was successfully created.
Now we have to save our image to the floppy. Insert a 3.5 "floppy disk in drive A: and open the program rawwritewin. Set the path to the image you just created (tutorial.img in my case) and click 'Write'.
If the floppy disk is in good condition and you followed the steps correctly, you should receive back a message indicating that the image was successfully saved on the floppy (make sure he is not write-protected).
Now just test. Put the floppy in the drive, restart the computer, configure the BIOS to boot from the floppy and if everything went right, you will see the following message after boot:
If this message appeared, congratulations, you did everything correctly. If it did not appear, review the tutorial that you're sure to find the location of the error.
That's it. I hope I have helped those beginners (like me) who had always wanted to know how to make an operating system and how it behaves. Of course, this was the most basic example, just the kick-start, but surely that's enough for you to go a little.
I suggest now trying to implement some commands in your OS (like I did in my experiments) as 'Clear Screen', 'Reboot', 'Help', etc..
Good luck and in the next tutorial, various implements, and adding graphics.