Writing A Bootloader Blog of Osanda
Writing A Bootloader Blog of Osanda
Writing a Bootloader
10 Comments
What is a Bootloader?
A bootloader is a special program that is executed each time a bootable device is initialized
by the computer during its power on or reset that will load the kernel image into the
memory. This application is very close to hardware and to the architecture of the CPU. All
x86 PCs boot in Real Mode. In this mode you have only 16-bit instructions. Our bootloader
runs in Real Mode and our bootloader is a 16-bit program.
(http://3.bp.blogspot.com/-
sud9r1AI3ng/Tgw8GRFxZfI/AAAAAAAAAEY/Rj-2srWrWkI/s320/bootProcess.jpg)
When you switch on the PC the BIOS want to boot up an OS which must be found
somewhere in hard disks, floppy disk, CDs, etc. The order in which BIOS searches an OS is
user configurable. Next the BIOS reads the first 512 byte sector of the bootable disk. Usually
a sector is 512 bytes in size. This is known as the Master Boot Record (MBR). BIOS simply
a sector is 512 bytes in size. This is known as the Master Boot Record (MBR). BIOS simply
loads the contents of the MBR into memory location “0x7c00” and jumps to that location to
start executing whatever code is in the MBR. Our bootloader should be 512 bytes in size as
well.
(http://4.bp.blogspot.com/-XfOu3tS1O-
I/Tgw9J2X1wNI/AAAAAAAAAEc/es0SCTcCpns/s320/masterBootRecord.jpg)
BIOS Interrupts
These interrupts help OS and application invoke the facilities of the BIOS. This is loaded
before the bootloader and it is very helpful in communicating with the I/O. Since we don’t
have OS level interrupts this is the only option that would be helpful.
For example to print a character to the screen using BIOS interrupt calls.
/*
Disk description table, to make it a valid floppy
FAT12 file system format
*/
jmp _start
.byte 144 #NOP
.ascii "OsandaOS" #OEMLabel
.word 512 #BytesPerSector
.byte 1 #SectorsPerCluster
.word 1 #ReservedForBoot
.byte 2 #NumberOfFats
.word 224 #RootDirEntries (224 * 32 = 7168 = 14
.word 2880 #LogicalSectors
.byte 0xf0 #MediumByte
.word 9 #SectorsPerFat
.word 18 #SectorsPerTrack
.word 2 #Sides
.long 0 #HiddenSectors
.byte 0 #LargeSectors
.byte 0 #DriveNo
.byte 0x29 #Signature (41 for Floppy)
.long 0x12345678 #VolumeID
.ascii "My First OS" #VolumeLabel
.ascii "FAT12 " #FileSystem
_start:
movw $0, %ax
movw %ax, %ss
movw %ax, %ds
movw %ax, %es
movw $string, %si
loop:
movb $0xe, %ah
movb (%si), %al
cmpb $0, %al
je done
int $0x10
addw $1, %si
jmp loop
done:
jmp done #infinite loop
string:
.ascii "Welcome to @OsandaMalith's First OS :)"
.byte 0
.fill 0x1fe - (. - main) ,1,0 #Pad remainder of boot sector with
.word 0xaa55 #The standard PC boot signature
https://github.com/OsandaMalith/bootloader/blob/master/loader.S
(https://github.com/OsandaMalith/bootloader/blob/master/loader.S)
Assembly and link the code. I have explicitly specified to load the text section to load to
0x7c00 and it will calculate the absolute addressing.
BITS 16
_start:
mov ax, 07C0h ; move 0x7c00 into ax
mov ds, ax ; set data segment to where we're
https://github.com/OsandaMalith/bootloader/blob/master/loader.nasm
(https://github.com/OsandaMalith/bootloader/blob/master/loader.nasm)
Assemble the file using binary as the format.
If you use the file utility you will see that it’s a legit 1.4MB floppy Disk and a 32-bit boot
sector.
$ file loader.bin
loader.bin: DOS floppy 1440k, x86 hard disk boot sector
If you open our bootloader in a hex editor you will see our 512 size program and at the end
If you open our bootloader in a hex editor you will see our 512 size program and at the end
there should be our boot signature 0xaa55.
(http://i.imgur.com/C4xAjZD.png)
You can also convert the binary file to an ISO using tools such as UltraISO, etc. You may
burn and try in your PC instead of emulating.
Use Qemu to test our newly created bootloader
qemu-system-i386 -fda floppy.flp
(http://i.imgur.com/qxcXdnR.png)
You can develop something like this
(http://i.imgur.com/hbWJcPS.png)
(http://i.imgur.com/piuMGZC.jpg)
Bootloader In C
We can use inline assembly using C to write a simple bootloader. I’ll be showing a simple
example to print “Hello”.
1 __asm__(".code16\n");
2 __asm__("jmpl $0x0000, $main\n");
3
4 void main() {
5 __asm__ __volatile__("movb $'H' , %al\n");
6 __asm__ __volatile__("movb $0x0e, %ah\n");
7 __asm__ __volatile__("int $0x10\n");
8
9 __asm__ __volatile__("movb $'e' , %al\n");
10 __asm__ __volatile__("movb $0x0e, %ah\n");
11 __asm__ __volatile__("int $0x10\n");
12
13 __asm__ __volatile__("movb $'l' , %al\n");
14 __asm__ __volatile__("movb $0x0e, %ah\n");
15 __asm__ __volatile__("int $0x10\n");
16
17 __asm__ __volatile__("movb $'l' , %al\n");
18 __asm__ __volatile__("movb $0x0e, %ah\n");
19 __asm__ __volatile__("int $0x10\n");
20
21 __asm__ __volatile__("movb $'o' , %al\n");
22 __asm__ __volatile__("movb $0x0e, %ah\n");
23 __asm__ __volatile__("int $0x10\n");
24
25 }
https://github.com/OsandaMalith/bootloader/blob/master/loader.c
(https://github.com/OsandaMalith/bootloader/blob/master/loader.c)
This will be the linker script specified in the linker as “test.ld”.ENTRY(main);
1 SECTIONS
2 {
3 . = 0x7C00;
4 .text : AT(0x7C00){ *(.text); }
5 .sig : AT(0x7DFE) { SHORT(0xaa55); }
6 }
https://github.com/OsandaMalith/bootloader/blob/master/test.ld
(https://github.com/OsandaMalith/bootloader/blob/master/test.ld)
After that compile using GCC and we generate only a object file and manually link using
the linker specifying our linker script.
(http://i.imgur.com/bOLp9BU.png)
Using BIOS interrupts you can write nice programs to the boot sector of your PC
References
http://duartes.org/gustavo/blog/post/how-computers-boot-up/
(http://duartes.org/gustavo/blog/post/how-computers-boot-up/)
http://wiki.osdev.org (http://wiki.osdev.org)
http://mikeos.sourceforge.net/ (http://mikeos.sourceforge.net/)
https://en.wikipedia.org/wiki/BIOS_interrupt_call
(https://en.wikipedia.org/wiki/BIOS_interrupt_call)
About these ads (https://wordpress.com/about-these-ads/)
1. Did this
21 year-old invent the solution
to global warming? an hour ago
Posted by Osanda Malith in Uncategorized
Tagged: assembly, bootloader, reverse
1. Conslight says:
October 26, 2015 at 8:07 pm
Time for you to code your own Kernel now
Reply
Osanda Malith says:
October 26, 2015 at 8:08 pm
yep
Reply
2. Dimitrios Kalemis says:
Reply
Osanda Malith says:
October 26, 2015 at 9:06 pm
Thank you very much Sir!
Reply
3. kokila alupotha says:
October 26, 2015 at 9:13 pm
cool post I hope to spent hours on this topic tomorrow thanks for the great article
Reply
Osanda Malith says:
October 26, 2015 at 9:44 pm
Thank you :))
Reply
4. Rusconnect Gray Hat says:
October 26, 2015 at 9:22 pm
Great inspiring write-up brother
Reply
Osanda Malith says:
October 26, 2015 at 9:44 pm
Thanks!
Reply
5. Prasad says:
October 27, 2015 at 9:56 am
Great one as always . Bookmarked
Reply
Osanda Malith says:
October 27, 2015 at 11:34 am
Thank You
Reply