Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / ASM

Debugging and Building Operating Systems

4.67/5 (25 votes)
29 Nov 2006CPOL8 min read 1   1.2K  
How to build and test your own Operating System.

Image 1

Figure 1 - Running other Operating Systems in your current OS with a PC Emulator.

Introduction

I think that one of the most important ways of being a real professional programmer is to design and build an Operating System. It is not enough to read how an OS works, you have to build one with your own hands.

Now, I would list what you will gain from learning how to develop an Operating System:

  1. A programmer is like an astronaut in space, the more he knows about the spaceship he is flying, and how to fix it in case of a problem, it is more likely that he would return safely back to earth. In the case of a programmer, the more he knows about the PC and the Operating system, his programs would be more reliable, stronger, and faster, and with less bugs.
  2. Learning the executables file format (helps a lot).
  3. Learning the Assembler (Every one would admit, that knowing assembler is a wonderful thing).
  4. Knowing what goes on behind the scenes.
  5. Learning the hardware of the Computer (CPU architecture, PCI, SATA, cash, Network card, ATA/ATAPI, etc.).
  6. Learning a lot of new tricks that can help you a lot in other kinds of programming.
  7. Learning all this would improve the programs you write a lot (even for regular Win32 user interface programming).

If you are not yet convinced, try it out and you would see how much fun it is to program Operating Systems.

This article is the second part of my previous article.

In this article, I would:

  1. Show you how to test and debug your Operating System in a very easy way.
  2. Build and test your own mother board.
  3. When resetting the drive with INT 13h, move the drive number to the register DL.

How to debug and test Operating Systems (the best and easiest way)

Image 2

Figure 2 – Bochs in work (Bochs is running my Boot sector from my other article).

For debugging and testing an OS you must have an x86 emulator, we would use Bochs.

Bochs is a portable open source x86 and AMD64 PCs emulator mostly written in C++ and distributed under the GNU Lesser General Public License. It supports emulation of processor(s) (including protected mode), memory, disks, display, Ethernet, BIOS and common hardware peripherals of PCs.

Many guest operating systems can be run using the emulator, including DOS, several versions of Windows, BSDs, and Linux. Bochs can run on many host operating systems, including Windows, Linux, Mac OS X and the Xbox.

Bochs is mostly used for operating system development (when an emulated operating system crashes, it does not crash the host operating system, so the emulated OS can be debugged) and to run other guest operating systems inside already running host operating systems. Some people use it to run old computer games inside their non-compatible computers.

To use Bochs, follow these steps:

  1. Download Bochs from here (it is free).
  2. Install Bochs.
  3. Open the directory were you installed Bochs.
  4. Look for bochsdbg.exe (the emulator + debugger), and bochs.exe (emulator), and bximage.exe (disk image creator).
  5. Start bximage.exe and follow the instructions to create a virtual 1.44 MB (1,474,560 bytes) floppy disk image.
  6. Create a file name bochsrc.txt (this file is the initialization file for the emulator) and enter in this string: floppya: image="MyOS.img", status=inserted. You can replace the file name MyOS.img with any file name you want (it must be the file that bximage.exe created (or any file of the right size)).
  7. Now, you need some kind of binaries to replace the image (you can take the BOOT.bin file from my first article and replace it in the first 512 bytes of the image you created.
  8. Now, run bochs.exe, and it would open two windows: <!--?xml:namespace prefix = st1 /--><st1:metricconverter productid="1. a" w:st="on">a console window (for debugging) <st1:metricconverter productid="2. a" w:st="on">and a GUI window (this window simulates a screen of the emulated OS).
  9. You can run your image with bochsdbg.exe for debugging.
  10. You can create floppies' images, hard disk images, and CD-ROM (*.iso) images, and replace on them any Operating System you want (like WinXP etc.) and debug them.
  11. Read the documentation that comes with Bochs and learn how to set break points (lb 0x7c00), dump memory (x /100bx 0x7c00), single stepping (s 1), read registers (r), continue execution (c), dump all CPU registers (dump_cpu) etc.
  12. Enjoy!

Image 3

Figure 3 – Bochs folder, and a simple configuration file.

A more advanced look at Bochs

Image 4

Figure 4 – a typical mother-board.

All this you can build with Bochs by only writing a simple configuration to a text file. This is why Bochs is so wonderful:

You can configure and build a whole PC, all you need to do is write the PC configuration to some text file (for example, bochsrc.txt) and place it in the Bochs folder. Here is an example of an advanced configuration file:

#=======================================================================
# ROM-IMAGE:
#=======================================================================
romimage: file=$BXSHARE/BIOS-bochs-latest, address=0xf0000
#=======================================================================
# CPU:
#=======================================================================
cpu: count=1, ips=10000000, reset_on_triple_fault=1
#=======================================================================
# Amount of RAM in MB
#=======================================================================
megs: 32
#=======================================================================
# VGA ROM IMAGE
#=======================================================================
vgaromimage: file= $BXSHARE/VGABIOS-lgpl-latest
#=======================================================================
# VGA:
#=======================================================================
vga: extension= vbe
#=======================================================================
# FLOPPY:
#=======================================================================
floppya: 1_44= "MyImg.img" , status=inserted
#=======================================================================
# ATA0, ATA1, ATA2, ATA3 (Set up Hard disk and CD-ROM IRQ's and I/O address)
#=======================================================================
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15
ata2: enabled=0, ioaddr1=0x1e8, ioaddr2=0x3e0, irq=11
ata3: enabled=0, ioaddr1=0x168, ioaddr2=0x360, irq=9

#=======================================================================
# ATA[0-3]-MASTER, ATA[0-3]-SLAVE
#=======================================================================
ata0-master: type=disk, path="MyOS\c.img" , mode=flat, 
             cylinders=20, heads=16, spt=63, translation=none
ata1-master: type=disk, path="MyOS\d.img" , mode=flat, 
             cylinders=2, heads=16, spt=63, translation=none
ata0-slave: type=cdrom, path=MyOS\cdrom.iso, status=inserted
ata1-slave: type=cdrom, path=MyOS\E.iso, status=inserted 
#=======================================================================
# BOOT from:
#=======================================================================
boot: disk
#=======================================================================
# COM1, COM2, COM3, COM4:
#=======================================================================
 Com1: enabled=1,  dev="COM1"
#=======================================================================
# Parallel ports
#=======================================================================
parport1: enabled=1, file="LPT1"
#=======================================================================
# SB16:
# This defines the SB16 sound emulation.
#=======================================================================

sb16: midimode=1, midi=/dev/midi00, wavemode=1, wave=/dev/dsp, 
      loglevel=2, log=sb16.log, dmatimer=600000

#=======================================================================
# VGA_UPDATE_INTERVAL:
#=======================================================================
vga_update_interval: 300000

#=======================================================================
# MOUSE: support:
#=======================================================================
mouse: enabled=0
#=======================================================================
# ne2k: NE2000 compatible ethernet adapter 
#      (Now you can connect to the Internet):
#=======================================================================
ne2k: ioaddr=0x240, irq=9, mac=b0:c4:20:00:00:01, 
      ethmod=vnet, ethdev="c:/temp"

#=======================================================================
# I440FXSUPPORT: PCI-Controller:
#=======================================================================
i440fxsupport: enabled=1

#=======================================================================
# USB1:
#=======================================================================
usb1: enabled=1

#=======================================================================
# CMOSIMAGE:
#=======================================================================
#cmosimage: file=cmos.img, rtc_init=time0

#-------------------------
# PCI host device mapping (Inserting a PCI device).
#-------------------------
pcidev: vendor=0x1234, device=0x5678

#=======================================================================
# GDBSTUB: (GDB debugger)
#=======================================================================
#gdbstub: enabled=0, port=1234, text_base=0, data_base=0, bss_base=0
#=======================================================================
# IPS: (Instruction Per seconds)
#=======================================================================
ips: 10000000

#=======================================================================
# FOR MORE INFORMATION !!!!!
#=======================================================================
#For more information see the Bches Documentation 
#and "bochsrc-sample.txt" (this is in the Bochs directory).

Have you ever known how easy it is to build a PC, you only have to write a couple of lines and run Bochs, and you have your own PC.

Here are some very useful debug commands:

  1. c (continue executing).
  2. s [count] (execute count instructions, default is 1) - for example, s.
  3. Ctrl+C (stop execution, and return to command line prompt).
  4. lb addr (set a linear address instruction breakpoint) - for example, lb 0x7C00.
  5. d n (delete a break point) - for example, d 1.
  6. x /nuf addr (dump memory of a physical address) - for example, X /100bx 0x7C00 (dump 100 bytes (b) display in HEX format (X) at address 0x7c00).
  7. r (list of CPU registers and their contents).
  8. info tab (show paging address translation).
  9. dump_cpu (dump complete CPU state).
  10. set reg = expr (change a CPU register to the value of an expression) - for example, set esi = 2*eax+ebx.

For more information, check the documentation that comes with Bochs.

Conclusion

Now I am sure you feel like a PC engineer working for some mother-board company. This configuration is a very wonderful thing, because you can build any kind of PC you want, and test your OS on it.

Another very good thing in Bochs is that it comes with source code, so it is like having all the hardware specification from the OS developer point of view. Also, it can help a lot for debugging your OS, because from the source code, you can know exactly what is wrong.

This is a list of Terms that may be new for you:

  1. ATA (the protocol for r<st1:place w:st="on"><st1:city w:st="on">eading and writing to hard disks).
  2. ATAPI (the protocol for r<st1:place w:st="on"><st1:city w:st="on">eading and writing to CD-ROMs).
  3. CMOS (a RAM chip on your mother board that is powered by a battery, this RAM saves all your PC settings that you see when entering the BIOS setup (what shows up when you press the Delete key when you start you computer) - this is really called CMOS setup).
  4. ROM Image (Read Only memory that holds your BIOS and permanent hardware settings).
  5. IPS (Instruction Per Second that your CPU can execute).
  6. VGA (Video Graphics Adapter).
  7. VGA update interval
  8. GDB (a debugger for debugging other Operating Systems from a different computer).
  9. PCI (Peripheral Component Interconnect - this is a standard that describes how to connect the peripheral components of a system together in a structured and controlled way).

Points of Interest

You can get the source code of Bochs (also for compiling with MSVC 6). I needed to do some hacking to get Bochs to compile with MSVC 6 and MSVS 2005. If you have compiled it, how did it compile for you? And what happened if you changed some of the #define identifier values, for example, #define BX_DEBUGGER 1 (in Config.h): did you successfully compile it?

Another good PC emulator (but it can't debug the OS) is Microsoft PC Emulator (you can download it from the Microsoft web site).

If you have any questions or you need help, feel comfortable to send me an e-mail. If you have a subject or a point you want me to write about, please note it in the forums (this would help a lot for future articles).

Here you can download the new source code to my Boot sector program from my first article.

These are the fixes I made in the BOOT Sector:

  1. When it finishes reading a track, it switches to the other side.
  2. I added the BIOS Parameter Block to make the diskette (or the hard disk) a valid FAT diskette.
  3. When resetting the drive with INT 13h, move the drive number to the register DL.

I would continue writing if I see this article interests people.

The next in this series of articles that I would write would go in to the details of developing your own OS, for example, details like OS design, programming the file system, EXE format, setting up for Protected mode, switching to Protected mode, handling interrupts, programming the PIC, writing an ATA/ATAPI driver, writing a floppy driver, DMA, using BIOS32 (a special BIOS interface for Protected mode), writing your kernel with MSVC, driver for graphics display, stage 1 and 2 of loading the OS etc.

These are the tools you would need:

  1. A good Hex editor (I am using Hex workshop (but it is not free)). I'm sure you would find a free Hex editor very easily in the Internet.
  2. MASM (v7-v8) (it is very easy to find a site that you can download it from).
  3. MSVC 6 (or v7-v8) (Microsoft C++ compiler).
  4. OllyDbg (a good Win32 debugger).
  5. Bochs.
  6. Tasm (Borland turbo assembler, (for 16 bit OS loader)) – if you have trouble finding one, send me an e-mail.
  7. TC (Borland Turbo C++, (for 16 bit OS loader)) – if you have trouble finding one, send me an e-mail.

Links that would help you a lot

  1. OS-Dev this site is the best resource for OS – development, I ever saw.
  2. These are the forums of OS-Dev.
  3. The source code of the Linux Kernel can help you a lot, (another link to the Linux source code: www.kernel.org).
  4. Help and information on Linux Kernel can also help a lot.

License

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