- Getting the boot loader correct
- Up to now….
- Get commands and split
- My Implementation
- Hardware configuration
- Key board state
- Appendix A
If anyone thinks that, it is possible to build (or modify) an OS without putting any work or research in to it, I like to say that it is pretty much impossible.
Operating system can be called as the intermediate between computer applications (user) and Hardware. Here we are using assembly language to write the operating system.
We need some tools before proceeding (all of these work will be done in a Linux environment).
As you can’t ON/OFF your computer each time you want to test the code, we need a virtual machine (VMware, Virtual box, etc…)
Then we need a floppy image that can be used to use with our virtual machine. For that I used a shell script file. You have to place that at the place where kernel and boot assembly files are resting and run it (Better to use the command line for executing that file). You can find the file in appendix A.
Now everything is ready to proceed.
Getting the boot loader correct
First of all I must say I gust gone once through the boot loader and I didn’t try to understand it thoroughly. Just download it and going though some steps will get you through the getting the boot loader correct. But for completeness I will talk bit about boot loader
Boot loader have to be our first consideration as that is think which will boot (power up the PC and all registers are blanked and the microprocessor is set to a reset state.) our computer. Booting can be by writing some code to the first sector of the floppy disk which tell the computer to execute our code this is what we call boot loader (also known as bootstrap). (Dhanagopal, 2006)
Simple Structure of the boot loader (tinkernut)
Set the boot loader to preferred bit size(in our case it is 16 bits)
Boot loader code
Here we create space to launch our code and avoid any hardware conflicts and get the device numbered.
Then search for the file that we are going to load for execution.
Load it and set the file allocation table from it.
Create variables (like kernel name)
Handle the errors
Now we have to load the boot loader to the floppy disk. This can be done using nasm.
In this project we are mostly working with 16-bit registers. This is a system is similar (in the view of a programmer) to what we have in 8088, 8086 CPUs. They provide several 16-bit registers: AX, BX, CX, DX, SI, DI, BP, SP, CS, DS, SS, ES, IP, FLAGS. They only support up to one megabyte of memory and only operate in real mode. In this mode, a program may access any memory address, even the memory of other programs! This makes debugging and security very difficult! Also, program memory has to be divided into segments. Each segment cannot be larger than 64K.
In 80386 with 32-bit resisters we got extended registers as shown in the picture. To be backward compatible, AX still refers to the 16-bit register and EAX is used to refer to the extended 32-bit register. AX is the lower 16-bits of EAX just as AL is the lower 8-bits of AX (and EAX). There is no way to access the upper 16-bits of EAX directly. The other extended registers are EBX, ECX, EDX, ESI and EDI. Many of the other registers are extended as well. BP becomes EBP; SP becomes ESP; FLAGS becomes EFLAGS and IP becomes EIP. (Carter’s) (wikipedia)
Up to now….
I started my improvements on ‘JOSH’ which layers a good foundation to continue my work. Up to now it only has very little functionalities like, it will show you a welcome message and it allows you to enter commands in its shell.
Get commands and split
It allows a command with 5 operands. So after user enter his command and press enter it split that up in to 5 parts (using spaces) any other after that will be ignored. These will be stored in 5 different buffers. (Dhanagopal, 2006)
Here we will call get and spilt methods and then we will compare user input with valid commands. If it matches with a valid command shell will execute the corresponding code blocks to that command. Up to now our shell can identify 2 commands ‘ver’ and ‘exit’ first command show the version and second one reboots the computer.
Interrupts can be simply defined as a signal informing a program that an event has occurred. When a program receives an interrupt signal, it takes a specified action (which can be to ignore the signal). Interrupt signals can cause a program to suspend itself temporarily to service the interrupt.
Every interrupts has a number, and there can be up to 256 different interrupts. When an interrupt occurs, CS/IP/flags are pushed into the stack and running program will be stopped, then the interrupt handler will be invoked. It will return the control after handling the event. In the beginning of the memory we will store all interrupt handlers which is called the Interrupt Service Routine table. (Dhanagopal, 2006)
As improvements for existing OS ‘JOSH’ I added several functions and shell commands. Let’s go by one. What I did can be categorize into several topics
Key board state
With the welcome message I print the system date. This is done using 0x1A interrupt with AH = 0x04. Below is the corresponding assembly code. Below I have shown how century was printed on screen. Similarly year, month, date can be printed.
System time can be printed using the command ‘time’ in the shell. This is done using 0x1A interrupt with AH = 0x02. Below is the corresponding assembly code.
In lot of places you may find that I have added 0x30 which is 48 in decimal to the final value before printing in to screen. That is simply because we need to convert the hex value in to a ASCII value.
‘help’ command can be used to get the list of commands with can be used to retrieve other information. When someone enter a unknown (wrong) command he get a prompt saying
>> Unknown command or bad file name! Enter ‘help’ to get the list of commands.
Using this user can use my OS without referring to documentation. Actually it took lot of time to get that table right. 😀
‘hwconfig’ can be used to get some basic details about the computer hardware. This show details about the processor and IO devices and ports. This is done using 0x11 interrupt and CPUID command. Below is the corresponding assembly code.
Key board state
‘kbstate’ can be used to get some basic details about the keyboard state. Simply it what special keys are pressed. This show details about the processor and IO devices and ports. This is done using 0x16 interrupt with AH = 0x02. Below is the corresponding assembly code.
Carter’s, P. (n.d.). Paul Carter’s. Retrieved from Paul Carter’s: http://www.drpaulcarter.com/pcasm/
Dhanagopal, D. M. (2006). Dr. Mohan Raj Dhanagopal. Retrieved November, December 2010, from Dr. Mohan Raj Dhanagopal: http://www.mohanraj.info/josh.jsp
MikeOS. (n.d.). Retrieved from MikeOS: http://mikeos.berlios.de
tinkernut. (n.d.). Retrieved from tinkernut: http://tinkernut.com/archives/category/programming-tip
wikipedia. (n.d.). Retrieved from wikipedia: http://en.wikipedia.org/wiki/Assembly_language