Table of Content
Experiment and Programming Environment
We shall elect the following as our experiment
- A Linux system running on a virtual machine
The instructor will use:
- An x86 or x64 system Debian Linux system running on an Oracle VM VirtualBox virtual machine
On the x86 Debian Linux system, install required application packages by command,
apt-get install -y nasm qemu qemu-system hexedit
The above command must run as root on the Linux system. In the Debian system, you first switch to root by command
su
If you have installed and set up the sudo package. You can also use
sudo to run the above apt-get command to install the required
packages, i.e.,
sudo apt-get install -y nasm qemu qemu-system hexedit
CPU Emulator
QEMU is a CPU emulator. To view the specifications of the x86 system it emulates, we use view one of its manual page:
man qemu-system-i386
BIOS
The Basic Input/Output System (BIOS) contains the Bootstrap code that is the first code the CPU executes when we power on the system. The Bootstrap code is responsible for loading the OS. This begins to load the code in the boot sector typically located at the very first sector of a booting device, such as, a hard disk drive. A system may have multiple boot sectors. We term the first boot sector BIOS loads the Master Boot Sector (Master Boot Record or MBR) that in turns loads and executes code in other boot sectors or the operating system kernel. When you install and set up an operating system, the system installer writes the MBR code to the Master Boot Sector.
We can examine the code in the MBR using the following commands
cat /proc/diskstats
dd if=/dev/sda of=mbr.bin bs=512 count=1
hexedit mbr.bin
ndisasm -b16 -o7c00h mbr.bin > mbr.asm
vi mbr.asm
For more see https://thestarman.pcministry.com/asm/mbr/GRUB.htm.
Experimenting Boot Sector Code
We can write our own boot sector code. Although you can write the code to the disk’s boot sector, we run it in the emulated x86 system using QEMU. The following examples are from Nick Bundell.
Compiling and Running Boot Sector Code
For the programs given here, the procedure to compile and run the code are as follows, provided that the program to run is in file example.asm:
- Compile example.asm. Open a terminal window, run
nasm example.asm -f bin -o example.bin - Run example.asm on the x86 system emulated by the QEMU emulator. In the
terminal window, run
qemu-system-i386 -drive format=raw,file=example.bin \ -display curses \ -monitor telnet:127.0.0.1:54321,server,nowait - Open the QEMU monitor. Open another terminal window run
telnet 127.0.0.1 54321To quit the QEMU emulator, issue
quitcommand as in(qemu) quit
Example 0 Infinite Loop
Following the steps in the above, we do the following:
- Create boot0.asm. On the Linux system, create the boot0.asm file using either nano, vi, or
other editors if you have installed.
; boot0.asm ; a do-nothing infinite loop loop: jmp loop times 510-($-$$) db 0 dw 0xaa55 - Compile boot0.asm. Open a terminal window, run
nasm boot0.asm -f bin -o boot0.bin - Run boot0.asm on the x86 system emulated by the QEMU emulator. In the
terminal window, run
qemu-system-i386 -drive format=raw,file=boot0.bin \ -curses \ -monitor telnet:127.0.0.1:54321,server,nowait - Open the QEMU monitor. Open another terminal window run
telnet 127.0.0.1 54321To quit the QEMU emulator, issue
quitcommand as in(qemu) quit
Example 2 Printing a Message
Similarly, you can run and observe the following code.
; boot1.asm
; print Hello on console
mov ah, 0x0e
mov al, 'H'
int 0x10
mov al, 'e'
int 0x10
mov al, 'l'
int 0x10
mov al, 'l'
int 0x10
mov al, 'o'
int 0x10
jmp $
times 510-($-$$) db 0
dw 0xaa55