Search (using Google):  Web Karig

 

19 November 2003

(Revised 21 November 2003)

Boot sector

The boot sector is the first sector (512-byte chunk of space) on a disk. When you reboot your computer with a floppy disk in the drive, the computer loads the boot sector and runs the code found there.

My boot-sector code here has only the most basic functionality: It sets up the stack and the segment registers to ensure that code can function properly in real mode, and it calls a BIOS routine to print something to the screen so that you can see that it worked.

This code works with NASM. You might have to fiddle with it to make it work with other assemblers.

The code starts at absolute address 0x7C00, and it is real-mode (16-bit) code.

[ORG 0x7C00]
[BITS 16]

The first thing I do is set the current code segment to zero — it might be something else.

The address of the boot sector can be expressed in real mode as any of a number of segment:offset pairs. The address could be 0:0x7C00, or 0x07C0:0, or something else. If the address is 0:0x7C00, then the processor can call code anywhere in the bottom 64KB of memory (0:0x0000 to 0:0xFFFF) without using far calls or segment overrides. If the address is 0x07C0:0, then the memory in the code segment begins at the start of the boot sector, and we can't call code below that point without a far call or a segment override.

I want to reserve the bottom 64KB for real-mode code and data — Karig might use the real-mode BIOS services for loading data from and saving it to disk — so I want the code segment to be zero. The accepted way to change the code segment is with a far jump — in this case, to the next instruction.

		jmp	word 0:segzero

segzero:

Then I set all of the data-segment registers to the same segment as CS.

		mov	ax, cs
		mov	ds, ax
		mov	es, ax
		mov	fs, ax
		mov	gs, ax

Then I set up a return stack. I decided to put the stack in a different segment — namely, in the second 64KB chunk of memory (segment 0x1000). (Always disable interrupts whenever setting up a stack! An interrupt can happen at any time, and it needs to put things onto the stack!)

		cli
		mov	ax, 0x1000
		mov	ss, ax
		mov	sp, 0xFFFE
		sti

Now I verify that the boot sector loaded and that the stack is OK by calling a BIOS routine to print characters to the screen. Specifically, I use interrupt 0x10, function 9 to print "YYYYYYYY" on the screen in black letters on a green background.

		mov	al, 'Y'
		xor	bh, bh
		mov	bl, 0x20
		mov	cx, 8
		mov	ah, 9
		int	0x10

Finally, I need to halt the computer so that the CPU doesn't try executing random data in memory — such as something that causes the computer to reboot. I want to be sure that I can see the result on the screen after the code finishes executing.

		jmp	$

To ensure that the BIOS will recognize this chunk of code as a boot sector, we have to ensure that it is 512 bytes long, and that the last two bytes are 0x55 and 0xAA.

		times	510 - ($-$$) db 0
		db	0x55, 0xAA

Other pages on writing a boot sector

If you didn't find this page helpful, here are more pages (and ZIP files) for you to explore.

The Boot Sector
The Boot Process
FAT12 (floppy) boot sector
The booting process
"Hello world" boot loader by Daniel Faulkner
Making your own operating system
bootf02 boot strap by John Fine
Writing a bootsector by Jeff Weeks
Go! OS boot sector by Stanislav Karchebny

Check the index for other entries.