Introduction:
Before we started writing our code, there are some background knowlege.
Bootloader:
what is a bootloader?
A bootloader is a program that will load the kernel image into the memory, and jumps to it.
how does it works?
First when you press the power bottom, the bios will start first. And after the bios is loaded into the memory,
it will first check which device you want to boot and check the first sector(The MBR) of the device. If it is OK, the bios will put the MBR code into the memory address 0x7c00 and jump to it.
MBR:
what is MBR?
MBR is the abbreviation of master boot record. As the name suggest the code inside the MBR is the bootloader. In most cases, the MBR is in the first sector of your devices, such as the hard disk, floopy disk , compact disk and so on.
The size of the MBR is 512 bytes. There are many fields contains in a MBR.
a. code 440bytes
b. Disk signature 4 bytes.
c. null 2 bytes
d. Partition tables. 64bytes
e. MBR signature 2 bytes.
BIOS interrupt:
what is bios interrupt?
bios interrupt is a low level interrupt which is loaded before the bootloader. BIOS interrupt contains many useful functions which can communicate with the I/O without fully understand the architecture.
why using bios interrupt?
as I previous mentioned, bootloader is to load the kernel image into the memory, and therefore there is no os system call or drivers to help you communicate with the I/O. The best way and the most convenient way is to use the bios interrupt to handle the I/O.
Coding time:
After understand the information, it's time to write a simple hello world program in the boot loader.
Helloworld.S
.code16 .section .text .global main main: #FAT12 file system format #there is nothing to change in this part jmp start_prog .byte 0x90 .ascii "MicrMike" .word 512 .byte 1 .word 1 .byte 2 .word 224 .word 2880 .byte 0xf0 .word 9 .word 18 .word 2 .long 0 .long 2880 .byte 0 .byte 0 .byte 0x29 .long 0x19900303 .ascii "HELLO-OS " .ascii "FAT12 " .fill 18, 1, 0 start_prog: movw $0, %ax movw %ax, %ss movw %ax, %ds movw %ax, %es movw $msg, %si #using bios interrupt 10h #parameter of bios interrupt 10h #%ah: function number #%al: the offset of the message loop: movb $0xe, %ah movb (%si), %al cmpb $0, %al je fin int $0x10 addw $1, %si jmp loop fin: jmp fin msg: .ascii "Hello world!!." .byte 0 .org 0x1fe, 0x00 .word 0xaa55
P.S the above source code is using the at&t syntax. In this article I won't tell you how to write assembly, but you can google to find some great tutorial.
Comment:There are many things that is worth notice in the source code.
1. The red highlight is the FAT12 file system format. Do not change this part.
2. Since we are in the real mode and the ld will assume that the code is in 0x0, I need to initial the whole base register, such as ds, ss and so on.
3. In order to print a message on the screen, I use the bios interrupt.
bios interrupt 10h
%ah stores the function number, in this case use the $0xe.
%al stores the address of the message.
4. in the bottom of the code, don't forget to put the MBR signature, otherwise the bios will think the MBR is useless.
Compile:
1. use gcc to compile the source code:
gcc -c Helloworld.S
2. use ld to link the obj file into the binary:
ld -Ttext=0x0 --oformat binary Helloworld.o -o Helloworld.bin
3. use mkdosfs to create a virtual floppy disk
mkdosfs -C os.flp 1440
4. install the binary file into the virtual floppy disk by using dd
dd status=noxfer conv=notrunc if=$boot_bin of=os.flp
reference website:
Result:
using qemu to test the result.
qemu -fda os.flp
and you will see a hello world in the qemu.
http://duartes.org/gustavo/blog/post/how-computers-boot-up
No comments:
Post a Comment