Writing a Simple Operating System — from Scratch

(Jeff_L) #1

CHAPTER 2. COMPUTER ARCHITECTURE AND THE BOOT


PROCESS 5


especially when looking for bugs, to know exactly where an individual byte will be stored
on a storage device or in memory, so endianness is very important.
This is possibly the smallest program your computer could run, but it is a valid
program nonetheless, and we can test this in two ways, the second of which is much safer
and better suited to our kind of experiments:



  • Using whatever means your current operating system will allow, write this boot
    block to the first sector of a non-essential storage device (e.g. floppy disk or flash
    drive), then reboot the computer.

  • Use virtual machine software, such as VMWare or VirtualBox, and set the boot
    block code as a disk image of a virtual machine, then start-up the virtual machine.
    You can be sure this code has been loaded and executed if your computer simply
    hangs after booting, without a message such as “No operating system found”. This is the
    infinite loop at work, that we put at the start of the code. Without this loop the CPU
    would tear off, executing every subsequent instruction in memory, most of which will
    be random, uninitialised bytes, until it throws itself into some invalid state and either
    reboots or, by chance, stumbles upon and runs a BIOS routine that formats your main
    disk.
    Remember, it is us that program the computer, and the computer follows our in-
    structions blindly, fetching and executing them, until it is switched off; so we need to
    make sure that it executes our crafted code rather than random bytes of data held some-
    where in memory. At this low level, we have a lot of power and responsibility over our
    computer, so we need to learn how to control it.


2.3 CPU Emulation


There is athird, more convenient option for testing these low-level programs without
continuously having to reboot a machine or risk scrubbing your important data off a
disk, and that is to use a CPU emulator such as Bochs or QEmu. Unlike machine
virtualisation (e.g. VMware, VirtualBox), which tries to optimise for performance and
therefore usage of the hosted operating system by running guest instructions directly on
the CPU, emulation involves a program that behaves like a specific CPU architecture,
using variables to represent CPU registers and high-level control structures to simulate
lower level jumps and so on, so is much slower but often better suited for development
and debugging such systems.
Note that, in order to do anything useful with an emulator, you need to give it some
code to run in the form of a disk image file. An image file simply is the raw data (i.e.
machine code and data) that would otherwise have been written to medium of a hard
disk, a floppy disk, a CDROM, USB stick, etc. Indeed, some emulators will successfully
boot and run a real operating system from an image file downloaded or extracted from
an installation CDROM --- though virtualisation is better suited to this kind of use.
The emulators translate low-level display device instructions into pixel rendering on
a desktop window, so you can see exactly what would be rendered on a real monitor.
In general, and for the exercises in this document, it follows that any machine code
that runs correctly under an emulator will run correctly on the real architecture ---
though obviously must faster.

Free download pdf