summaryrefslogtreecommitdiff
path: root/src/asm/boot.asm
diff options
context:
space:
mode:
Diffstat (limited to 'src/asm/boot.asm')
-rw-r--r--src/asm/boot.asm161
1 files changed, 161 insertions, 0 deletions
diff --git a/src/asm/boot.asm b/src/asm/boot.asm
new file mode 100644
index 0000000..ae68761
--- /dev/null
+++ b/src/asm/boot.asm
@@ -0,0 +1,161 @@
+[BITS 32]
+
+; Declare constants for the multiboot header.
+MBALIGN equ 1 << 0 ; align loaded modules on page boundaries
+MEMINFO equ 1 << 1 ; provide memory map
+MBFLAGS equ MBALIGN | MEMINFO ; this is the Multiboot 'flag' field
+MAGIC equ 0x1BADB002 ; 'magic number' lets bootloader find the header
+CHECKSUM equ -(MAGIC + MBFLAGS) ; checksum of above, to prove we are multiboot
+
+; Declare a multiboot header that marks the program as a kernel. These are magic
+; values that are documented in the multiboot standard. The bootloader will
+; search for this signature in the first 8 KiB of the kernel file, aligned at a
+; 32-bit boundary. The signature is in its own section so the header can be
+; forced to be within the first 8 KiB of the kernel file.
+section .multiboot
+align 4
+ dd MAGIC
+ dd MBFLAGS
+ dd CHECKSUM
+
+section .bootstrap
+
+present equ 1 << 7
+not_sys equ 1 << 4
+exec equ 1 << 3
+cd equ 1 << 2
+rw equ 1 << 1
+access equ 1 << 0
+
+gran_4k equ 1 << 7
+sz_32 equ 1 << 6
+long_m equ 1 << 5
+
+global gdt.ptr
+gdt:
+.null: equ $ - gdt
+ dq 0
+.code: equ $ - gdt
+ dd 0xffff
+ db 0
+ db present | not_sys | exec | rw
+ db gran_4k | long_m | 0xf
+ db 0
+.data: equ $ - gdt
+ dd 0xffff
+ db 0
+ db present | not_sys | rw
+ db gran_4k | sz_32 | 0xf
+ db 0
+.ptr:
+ dw $ - gdt - 1
+ dq gdt
+
+global bootstrap
+bootstrap:
+
+ mov dword [multiboot_magic], eax
+ mov dword [multiboot_header], ebx
+
+ mov eax, cr0
+ and eax, ~(1 << 31)
+ mov cr0, eax
+
+ mov edi, pml4 ;0x1000
+ mov cr3, edi
+ xor eax, eax
+ mov ecx, 1024
+ rep stosd
+
+ mov edi, 0x2000
+ mov ecx, 4096
+ rep stosd
+
+ mov edi, cr3
+
+ mov dword [edi], 0x2003
+ mov edi, 0x2000
+ mov dword [edi], 0x3003
+ add edi, 0x1000
+ mov dword [edi], 0x4003
+ mov dword [edi + 8], 0x5003
+ add edi, 0x1000
+
+ mov ebx, 0x00000003
+ mov ecx, 512
+
+.set_entry:
+ mov dword [edi], ebx
+ add ebx, 0x1000
+ add edi, 8
+ loop .set_entry
+
+ mov edi, 0x5000
+ mov ecx, 512
+
+.set_entry_2:
+ mov dword [edi], ebx
+ add ebx, 0x1000
+ add edi, 8
+ loop .set_entry_2
+
+ mov eax, cr4
+ or eax, 1 << 5
+ mov cr4, eax
+
+ mov ecx, 0xc0000080
+ rdmsr
+ or eax, 1 << 8 | 1 << 0
+ wrmsr
+
+ mov eax, cr0
+ or eax, 1 << 31
+ mov cr0, eax
+
+ lgdt [gdt.ptr]
+
+ mov ax, gdt.data
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+
+ extern start
+ jmp gdt.code:start
+
+global set_pml4
+set_pml4:
+ mov ecx, 0xC000080
+ rdmsr
+ and eax, ~(1 << 8)
+ wrmsr
+
+ mov eax, cr0
+ and eax, ~(1 << 31)
+ mov cr0, eax
+
+ mov cr3, edi
+
+ mov ecx, 0xC000080
+ rdmsr
+ or eax, 1 << 8
+ wrmsr
+
+ mov eax, cr0
+ or eax, 1 << 31
+ mov cr0, eax
+
+ retf
+
+section .data
+align 16
+global multiboot_header
+multiboot_header: dq 0
+global multiboot_magic
+multiboot_magic: dq 0
+
+section .bss
+global pml4
+align 4096
+pml4: resq 512