Booting the machine is the first step towards writing your own operating system. You’re the wind, baby.
1. Download and install the latest version of FASM (Flat Assembler), if you have not already done so. Details are given in a previous tutoral.
2. Download the latest version of QEMU, by Fabrice Bellard. QEMU is an open-source processor emulator, and is available as source code at http://qemu.org. Unfortunately, no precompiled binaries are available on the QEMU site itself. However, a link is provided to an “unofficial” archive of Windows binaries, which as of this writing is available at http://homepage3.nifty.com/takeda-toshiya/.
3. Install QEMU by uncompressing the archive file to any desired directory. Make a note of where the file “qemu.exe” is located.
4. In any convenient location, create a new directory named “HelloWorldBootable”.
5. In the newly created HelloWorldBootable directory, create a new text file named “HelloWorldBootable.asm”, containing the following text.
use16 ; 16-bit mode org 0x7C00 ; this is the address of the boot sector BootStageOne: ; mov ah,0x00 ; reset disk mov dl,0 ; drive number int 0x13 ; call BIOS interrupt routine ; ; load the sector from disk using BIOS interrupt 0x13 mov ah,0x02 ; read sectors into memory mov al,1 ; number of sectors to read mov dl,0 ; drive number mov ch,0 ; cylinder number mov dh,0 ; head number mov cl,2 ; starting sector number mov bx,Main ; memory location to load to int 0x13 ; call BIOS interrupt routine ; jmp Main ; now that it's been loaded ; PadOutSectorOneWithZeroes: ; pad out all but the last two bytes of the sector with zeroes times ((0x200 - 2) - ($ - $$)) db 0x00 BootSectorSignature: dw 0xAA55 ; these must be the last two bytes in the boot sector ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; org 0x7E00 ; the address of the sector after the boot sector Main: mov si,TextHelloWorld ; point the si register at the string to display mov ah,0x0E ; for int 0x10: write chars in teletype mode ForEachChar: ; begin loop lodsb ; load al with what si points to, increment si cmp al,0x00 ; if char is null... je EndForEachChar ; .. then break out of the loop int 0x10 ; call interrupt 0x10 (BIOS: print char) jmp ForEachChar ; jump back to beginning of loop EndForEachChar: ; end of the loop ret ; quit the program ; data to display TextHelloWorld: db 'Hello, world!',0 PadOutSectorTwoWithZeroes: times ((0x200) - ($ - $$)) db 0x00
6. Still in the HelloWorldBootable directory, create a new text file named “BuildEnvironmentSetup-FasmQemu.bat”, containing the following text. Substitute the names of the directories containing fasm.exe and qemu.exe in the appropriate places. Don’t put quotes around the directory paths–FASM doesn’t seem to understand them.
set fasmPath=[the directory where fasm is located] set qemuPath=[the directory where qemu is located] for %%* in (.) do (set programName=%%~n*)'
7. Still in the HelloWorldBootable directory, create a new text file named “ProgramBuildAndRun-FasmQemu.bat”, containing the following text.
call BuildEnvironmentSetup-FasmQemu.bat %fasmPath%\fasm.exe %programName%.asm %programName%.img %qemuPath%\qemu.exe -boot a -fda %programName%.img pause
8. Double-click the icon for ProgramBuildAndRun-FasmQemu.bat to run it. A console window will appear, FASM will assemble the code in the asm file into a binary img file, and then QEMU will attempt to boot from this binary file. A QEMU window should appear, and the text “Hello, World!” should be visible within it.
- Obviously, QEMU is only a simulation of a real machine. In order to actually boot an actual machine with this code, you need some way to write it to the physical sectors of a disk. Modern operating systems go out of their way to make that sort of thing difficult, for the very good reason that it’s an almost guaranteed way to accidentally turn an existing filesystem into a useless, smoking wreck. That being said, you could possibly use QEMU itself to write to a (hopefully blank) disk’s sectors directly, by mounting the source and destination disks on the command line you use to call QEMU, and using the BIOS disk read and write interrupt routines to transfer the sectors. For now, this is left as an exercise for the reader. Don’t say I didn’t warn you.
- Instead of QEMU, you could also boot this program in an alternate virtualization hypervisor, such as VirtualBox. For VirtualBox, create a new machine with “Other/Unknown” operating system, open its settings, click the “Storage” item, click the “Add New Controller” button under the Storage Tree box, and select “Add Floppy Controller” from the menu that appears. Then insert the .img file in the new floppy drive and start the virtual machine.