back to nasm
This commit is contained in:
106
src/boot.asm
Normal file
106
src/boot.asm
Normal file
@@ -0,0 +1,106 @@
|
||||
global _start
|
||||
extern kernel_main
|
||||
|
||||
%define FLAGS 0b10
|
||||
%define MAGIC 0x1BADB002
|
||||
%define CHECKSUM -(MAGIC + FLAGS)
|
||||
|
||||
section .multiboot
|
||||
align 4
|
||||
dd MAGIC
|
||||
dd FLAGS
|
||||
dd CHECKSUM
|
||||
|
||||
section .bss
|
||||
align 4096
|
||||
pml4_table:
|
||||
resb 4096
|
||||
pdpt_table:
|
||||
resb 4096
|
||||
pd_table:
|
||||
resb 4096
|
||||
|
||||
section .bss
|
||||
align 16
|
||||
stack_bottom:
|
||||
resb 16384
|
||||
stack_top:
|
||||
|
||||
section .data
|
||||
align 8
|
||||
gdt64:
|
||||
dq 0x0000000000000000
|
||||
.code:
|
||||
dq 0x00AF9A000000FFFF
|
||||
.descriptor:
|
||||
dw .end - gdt64 - 1
|
||||
dq gdt64
|
||||
.end:
|
||||
|
||||
section .text
|
||||
bits 32
|
||||
_start:
|
||||
mov esp, stack_top
|
||||
|
||||
; Multiboot will place a magic value in eax
|
||||
; If this magic value is not present, then we might not have multiboot info in ebx,
|
||||
; therefore we throw an error
|
||||
cmp eax, 0x2BADB002
|
||||
jne error
|
||||
|
||||
; Check if cpuid is available by flipping the 22-nth youngest bit
|
||||
; in the eflags register and checking if the cpu flipped it back
|
||||
pushfd
|
||||
pop eax
|
||||
mov ecx, eax
|
||||
xor eax, 1 << 21
|
||||
push eax
|
||||
popfd
|
||||
pushfd
|
||||
pop eax
|
||||
; If cpuid is available, eax should be different than ecx
|
||||
xor eax, ecx
|
||||
jz error
|
||||
; Finally restore eflags register to the original value
|
||||
push ecx
|
||||
popfd
|
||||
|
||||
; Check if extended cpuid is available by calling cpuid with 0x80000000,
|
||||
; If cpuid is available, eax will be greater than 0x80000000 after the call
|
||||
mov eax, 0x80000000
|
||||
cpuid
|
||||
cmp eax, 0x80000001
|
||||
jb error
|
||||
|
||||
; Check if long mode is available by calling cpuid with 0x80000001
|
||||
; this will place the extended features of the cpu in edx
|
||||
; The 30-nth youngest bit tells us if long mode is supported or not
|
||||
mov eax, 0x80000001
|
||||
cpuid
|
||||
test edx, 1 << 29
|
||||
jz error
|
||||
|
||||
; todo(nub31): setup paging
|
||||
; todo(nub31): enter long mode
|
||||
|
||||
; Load global descriptor table which is set up for 64 bit
|
||||
lgdt [gdt64.descriptor]
|
||||
|
||||
call kernel_main
|
||||
jmp error
|
||||
|
||||
error:
|
||||
cli
|
||||
mov byte [0xb8000], 'B'
|
||||
mov byte [0xb8002], 'O'
|
||||
mov byte [0xb8004], 'O'
|
||||
mov byte [0xb8006], 'T'
|
||||
mov byte [0xb8008], ' '
|
||||
mov byte [0xb800a], 'E'
|
||||
mov byte [0xb800c], 'R'
|
||||
mov byte [0xb800e], 'R'
|
||||
mov byte [0xb8010], 'O'
|
||||
mov byte [0xb8012], 'R'
|
||||
hang:
|
||||
hlt
|
||||
jmp hang
|
||||
108
src/boot.s
108
src/boot.s
@@ -1,108 +0,0 @@
|
||||
.intel_syntax noprefix
|
||||
|
||||
.set ALIGN, 1<<0
|
||||
.set MEMINFO, 1<<1
|
||||
.set FLAGS, ALIGN | MEMINFO
|
||||
.set MAGIC, 0x1BADB002
|
||||
.set CHECKSUM, -(MAGIC + FLAGS)
|
||||
|
||||
.section .multiboot
|
||||
.align 4
|
||||
.long MAGIC
|
||||
.long FLAGS
|
||||
.long CHECKSUM
|
||||
|
||||
.section .bss
|
||||
.align 4096
|
||||
pml4_table:
|
||||
.zero 4096
|
||||
pdpt_table:
|
||||
.zero 4096
|
||||
pd_table:
|
||||
.zero 4096
|
||||
|
||||
.section .bss
|
||||
.align 16
|
||||
stack_bottom:
|
||||
.skip 16384
|
||||
stack_top:
|
||||
|
||||
.section .data
|
||||
.align 8
|
||||
gdt64:
|
||||
.quad 0x0000000000000000
|
||||
gdt64_code:
|
||||
.quad 0x00AF9A000000FFFF
|
||||
gdt64_descriptor:
|
||||
.word gdt64_end - gdt64 - 1
|
||||
.long gdt64
|
||||
gdt64_end:
|
||||
|
||||
.section .text
|
||||
.code32
|
||||
.global _start
|
||||
_start:
|
||||
mov esp, stack_top
|
||||
|
||||
// Multiboot will place a magic value in eax
|
||||
// If this magic value is not present, then we might not have multiboot info in ebx,
|
||||
// therefore we throw an error
|
||||
cmp eax, 0x2BADB002
|
||||
jne error
|
||||
|
||||
// Check if cpuid is available by flipping the 22-nth youngest bit
|
||||
// in the eflags register and checking if the cpu flipped it back
|
||||
pushfd
|
||||
pop eax
|
||||
mov ecx, eax
|
||||
xor eax, 1 << 21
|
||||
push eax
|
||||
popfd
|
||||
pushfd
|
||||
pop eax
|
||||
// If cpuid is available, eax should be different than ecx
|
||||
xor eax, ecx
|
||||
jz error
|
||||
// Finally restore eflags register to the original value
|
||||
push ecx
|
||||
popfd
|
||||
|
||||
// Check if extended cpuid is available by calling cpuid with 0x80000000,
|
||||
// If cpuid is available, eax will be greater than 0x80000000 after the call
|
||||
mov eax, 0x80000000
|
||||
cpuid
|
||||
cmp eax, 0x80000001
|
||||
jb error
|
||||
|
||||
// Check if long mode is available by calling cpuid with 0x80000001
|
||||
// this will place the extended features of the cpu in edx
|
||||
// The 30-nth youngest bit tells us if long mode is supported or not
|
||||
mov eax, 0x80000001
|
||||
cpuid
|
||||
test edx, 1 << 29
|
||||
jz error
|
||||
|
||||
// todo(nub31): setup paging
|
||||
// todo(nub31): enter long mode
|
||||
|
||||
// Load global descriptor table which is set up for 64 bit
|
||||
lgdt [gdt64_descriptor]
|
||||
|
||||
call kernel_main
|
||||
jmp error
|
||||
|
||||
error:
|
||||
cli
|
||||
mov byte ptr [0xb8000], 'B'
|
||||
mov byte ptr [0xb8002], 'O'
|
||||
mov byte ptr [0xb8004], 'O'
|
||||
mov byte ptr [0xb8006], 'T'
|
||||
mov byte ptr [0xb8008], ' '
|
||||
mov byte ptr [0xb800a], 'E'
|
||||
mov byte ptr [0xb800c], 'R'
|
||||
mov byte ptr [0xb800e], 'R'
|
||||
mov byte ptr [0xb8010], 'O'
|
||||
mov byte ptr [0xb8012], 'R'
|
||||
hang:
|
||||
hlt
|
||||
jmp hang
|
||||
Reference in New Issue
Block a user