summaryrefslogtreecommitdiff
path: root/boot/boot.asm
diff options
context:
space:
mode:
authorAiden Gall <aiden@aidengall.xyz>2024-05-14 19:43:28 +0100
committerAiden Gall <aiden@aidengall.xyz>2024-05-14 19:51:05 +0100
commit93585dc4da3be099e1ffe7e757aa7caff2e1f013 (patch)
treec1335acdd74cff12e545ce386ab2dbd176eaa473 /boot/boot.asm
initial commit
Diffstat (limited to 'boot/boot.asm')
-rw-r--r--boot/boot.asm144
1 files changed, 144 insertions, 0 deletions
diff --git a/boot/boot.asm b/boot/boot.asm
new file mode 100644
index 0000000..eedde07
--- /dev/null
+++ b/boot/boot.asm
@@ -0,0 +1,144 @@
+format ELF64
+
+PML4_TABLE = 0x1000
+E820_MMAP = 0xf000
+
+MSR_EFER = 0xc0000080
+
+include 'bios.inc'
+include 'page.inc'
+include 'segdesc.inc'
+
+section '.text.boot' executable
+
+org 0x7c00
+use16
+ jmp far 0x0000:@f ; ensure cs = 0x0000
+@@:
+ xor ax, ax
+ mov ds, ax
+ mov es, ax
+
+ ; put stack directly bellow bootloader
+ mov ss, ax
+ mov sp, $$
+ cld
+
+ mov [boot_disk], dl
+
+ bios_disk_read ($$+0x200), 0, 0, 2, 57, disk_error
+
+ bios_e820_mmap E820_MMAP, e820_error
+
+ bios_a20_enable
+ bios_vga_write_mode_3
+
+ page_table_init_real PML4_TABLE
+
+ ; disable IRQs
+ mov al, 0xff
+ out 0xa1, al
+ out 0x21, al
+
+ lidt [dummy_idtr]
+
+ ; enable PAE (1<<5) and PGE (1<<7)
+ mov eax, (1 shl 7) or (1 shl 5)
+ mov cr4, eax
+
+ ; point cr3 at PML4
+ mov edx, edi
+ mov cr3, edx
+
+ ; enable long mode
+ mov ecx, MSR_EFER
+ rdmsr
+ or eax, (1 shl 8)
+ wrmsr
+
+ ; enable protected mode
+ mov ebx, cr0
+ or ebx, (1 shl 31) or (1 shl 0)
+ mov cr0, ebx
+
+ lgdt [gdtr]
+
+ jmp far (gdt.kcode-gdt):longmode
+
+e820_error:
+ ; change beginning of error message ("disk" -> "e820")
+ mov dword [errmsg], 0x30323865
+disk_error:
+ mov si, errmsg
+ mov ah, 0x0e
+ jmp @f
+.loop:
+ int 0x10
+@@:
+ lodsb
+ test al, al
+ jnz .loop
+
+ ; wait until keypress, then jump to reset vector (reboot)
+ xor ah, ah
+ int 0x16
+ jmp far 0xffff:0x0000
+
+use64
+longmode:
+ mov ax, (gdt.kdata-gdt)
+ mov ds, ax
+ mov es, ax
+ mov ss, ax
+
+ cli
+
+ ; copy kernel to 0x100000
+ mov ecx, (57*0x200)/8
+ mov esi, 0x7e00
+ mov edi, 0x100000
+ rep movsq
+
+ xor eax, eax
+ xor ebx, ebx
+ xor ecx, ecx
+ xor edx, edx
+ xor edi, edi
+
+ ; put stack at top of addressable memory
+ mov esp, 0x200000
+ mov ebp, esp
+
+ jmp 0x100000
+
+align 4
+dw 0
+label gdtr fword
+ .limit dw (gdt.sizeof - 1)
+ .addr dd gdt
+
+align 4
+errmsg db "disk error: press any key to reboot",0
+
+align 8
+gdt:
+ .null dq 0
+ .kcode seg_desc 0, 0, (GDT_CODE_64 or SEG_PRIV0)
+ .kdata seg_desc 0, 0, (GDT_DATA_64 or SEG_PRIV0)
+ .ucode seg_desc 0, 0, (GDT_CODE_64 or SEG_PRIV3)
+ .udata seg_desc 0, 0, (GDT_DATA_64 or SEG_PRIV3)
+ .sizeof = $ - gdt
+
+align 4
+boot_disk db 0, 0
+label dummy_idtr fword
+ .limit dw 0
+ .addr dd 0
+
+if ($-$$) <= 510
+ db 510-($-$$) dup 0
+else
+ display "ERR: boot sector image exceeds 512 bytes",10
+ assert ($-$$) <= 510
+end if
+db 0x55,0xaa