summaryrefslogtreecommitdiff
path: root/src/boot
diff options
context:
space:
mode:
Diffstat (limited to 'src/boot')
-rw-r--r--src/boot/bootloader.asm94
1 files changed, 94 insertions, 0 deletions
diff --git a/src/boot/bootloader.asm b/src/boot/bootloader.asm
new file mode 100644
index 0000000..f42e702
--- /dev/null
+++ b/src/boot/bootloader.asm
@@ -0,0 +1,94 @@
+ORG 0x7c00
+BITS 16
+
+CODE_SEG equ gdt_code - gdt_start ; 0x8
+DATA_SEG equ gdt_data - gdt_start ; 0x10
+_start:
+ jmp short start
+ nop
+
+; Setup dummy BIOS Parameter block so a dumb BIOS does not corrupt us
+; if it starts messing up with the parameter block
+ times 33 db 0
+
+start:
+ ; Set CS to 0 with label step2 as its beginning offset
+ jmp 0:step2
+
+step2:
+ ; Setup segments
+
+ cli ; Disable interrupts
+ mov ax, 0
+ mov ds, ax
+ mov es, ax
+ mov ss, ax
+ mov sp, 0x7c00 ; Stack segment starts right before ds
+ ; and grows down to 0x0. This works because
+ ; Intel implements a full descending stack
+ sti ; Enable interrupts
+
+.load_protected:
+ cli
+ lgdt[gdt_table]
+ mov eax, cr0
+ or eax, 0x1
+ mov cr0, eax
+ jmp CODE_SEG:start_32
+
+; GDT table description
+gdt_start:
+gdt_null: ; First segment Descriptor is always 0
+ dd 0x0
+ dd 0x0
+
+;Second segment descriptor... Code segment - 0x8
+gdt_code:
+ dw 0xffff ; Segment limit 0-15
+ dw 0 ; Base address 0-15
+ db 0 ; Base 16-23
+ db 0x9a ; Access byte field 0b10011010
+
+ ; We don't have a 4 bits type, so use a byte type
+ ; to set both Segment limit high bits and flags
+
+ db 11001111b ; Segment limit 16-19
+ ; Flags 0-3
+ db 0 ; Base address high bits 24-31
+
+;Second segment descriptor... Data segment - 0x10
+gdt_data:
+ dw 0xffff ; Segment limit 0-15
+ dw 0 ; Base address 0-15
+ db 0 ; Base 16-23
+ db 0x92 ; Access byte field 0b10010010
+ db 11001111b ; Segment limit 16-19
+ ; Flags 0-3
+ db 0 ; Base address high bits 24-31
+gdt_end:
+
+gdt_table:
+ dw gdt_end - gdt_start - 1
+ dd gdt_start
+
+
+[BITS 32]
+
+; No access to BIOS from now on....
+start_32:
+ ; Set all segments to the same as the DATA_SEG
+ mov ax, DATA_SEG
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+
+ ; Set the stack pointer and base pointer further in mem
+ mov ebp, 0x00200000
+ mov esp, ebp
+ jmp $
+
+; Fill in to the end and add bootloader signature
+ times 510 - ($ - $$) db 0
+ dw 0xAA55