summaryrefslogtreecommitdiff
path: root/kernel/entry.S
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2025-04-03 12:31:21 -0400
committerFreya Murphy <freya@freyacat.org>2025-04-03 12:31:21 -0400
commita524eb3846aac4d1b38f08cba49ff3503107042f (patch)
treedbe81fccf975f646a681e4fdcebd227cdfb98774 /kernel/entry.S
parentnew libs (diff)
downloadcomus-a524eb3846aac4d1b38f08cba49ff3503107042f.tar.gz
comus-a524eb3846aac4d1b38f08cba49ff3503107042f.tar.bz2
comus-a524eb3846aac4d1b38f08cba49ff3503107042f.zip
move old kernel code (for now) into kernel/old, trying to get long mode
Diffstat (limited to 'kernel/entry.S')
-rw-r--r--kernel/entry.S158
1 files changed, 158 insertions, 0 deletions
diff --git a/kernel/entry.S b/kernel/entry.S
new file mode 100644
index 0000000..5d763ed
--- /dev/null
+++ b/kernel/entry.S
@@ -0,0 +1,158 @@
+ .globl _start
+ .globl kernel_pml4
+ .globl kernel_pdpt_0
+ .globl kernel_pd_0
+ .globl kernel_pt_0
+ .globl paging_pt
+ .globl bootstrap_pt
+ .extern main
+ .extern GDT
+
+ .section .bss
+
+ # kernel page tables
+ .align 4096
+kernel_pml4: # reserve memory for initial 512 pml4 entires
+ .skip 4096
+kernel_pdpt_0: # reserve memory for initial 512 pdpt entires
+ .skip 4096
+kernel_pd_0: # reserve memory for initial 512 pd entries
+ .skip 4096
+kernel_pt_0: # reserve memory for initial 512 pt entries
+ .skip 4096
+paging_pt: # reserve pages for pager mappings
+ .skip 4096
+bootstrap_pt: # reserve pages to bootstrap pager
+ .skip 4096
+
+ # kernel stack
+ .align 16
+kern_stack_start:
+ .skip 8192
+kern_stack_end:
+
+ .section .rodata
+ .align 16
+
+ # access bits
+ .set PRESENT, 1 << 7
+ .set NOT_SYS, 1 << 4
+ .set EXEC, 1 << 3
+ .set DC, 1 << 2
+ .set RW, 1 << 1
+ .set ACCESSED, 1 << 0
+
+ # flag bits
+ .set GRAN_4K, 1 << 7
+ .set SZ_32, 1 << 6
+ .set LONG_MODE, 1 << 5
+
+ # kernel gdt (long mode)
+GDT:
+ GDT.Null:
+ .quad 0
+
+ GDT.Code:
+ .byte 0
+ .byte PRESENT | NOT_SYS | EXEC | RW
+ .byte GRAN_4K | LONG_MODE | 0xF
+ .byte 0
+
+ GDT.Data:
+ .long 0xFFFF
+ .byte 0
+ .byte PRESENT | NOT_SYS | RW
+ .byte GRAN_4K | SZ_32 | 0xF
+ .byte 0
+
+ GDT.TSS:
+ .long 0x00000068
+ .long 0x00CF8900
+
+ GDT.Pointer:
+ .short . - GDT - 1
+ .quad GDT - .
+
+ .section .text
+ .code32
+
+_start:
+ # enable interrupts
+ cli
+
+ # setup stack
+ movl $kern_stack_end, %esp
+ movl $kern_stack_end, %ebp
+
+ # save multiboot (if using multiboot)
+ pushl $0
+ push %ebx
+ pushl $0
+ push %eax
+
+ # zero out kernel page table
+ movl $0x1000, %edi # kernel is loaded at 0x1000
+ movl %edi, %cr3
+ xorl %eax, %eax
+ movl $4096, %ecx # zero 4096 pages
+ rep stosl
+ movl %cr3, %edi
+
+ # identity map kernel
+ movl $kernel_pdpt_0 + 3, (%edi) # Set the uint32_t at the desination index to 0x2003.
+ movl $kernel_pdpt_0, %edi # Add 0x1000 to the desination index.
+ movl $kernel_pd_0 + 3, (%edi) # Set the uint32_t at the desination index to 0x3003.
+ movl $kernel_pd_0, %edi # Add 0x1000 to the desination index.
+ movl $kernel_pt_0 + 3, (%edi) # Set the uint32_t at the desination index to 0x4003.
+ movl $kernel_pt_0, %edi # Add 0x1000 to the desination index.
+
+ movl $0x00000003, %ebx # Entry value to set
+ movl $512, %ecx # Loop count
+
+set_entry:
+ # set entires in mapping
+ movl %ebx, (%edi) # Set the uint32_t at the desination index to the B-register
+ addl $0x1000, %ebx # Add 0x1000 to the B-register
+ addl $8, %edi # Add eight to the desination index
+ loop set_entry
+
+ # enable page address extension
+ movl %cr4, %eax
+ orl $(1 << 5), %eax
+ movl %eax, %cr4
+
+ # enable long mode
+ movl $0xC0000080, %eax
+ rdmsr
+ orl $(1 << 8), %eax
+ wrmsr
+
+ # enable paging
+ movl %cr0, %eax
+ orl $(1 << 31), %eax
+ movl %eax, %cr0
+
+ # load gdt
+ lgdt GDT.Pointer
+ ljmp $16, $code64
+
+ .code64
+code64:
+
+ movw $16, %dx # set segment registers
+ movw %dx, %ds
+ movw %dx, %ss
+
+ xorq %rbp, %rbp # set ebp to 0 so we know where to end stack traces
+
+ pop %rdi # pop possible multiboot header
+ pop %rsi
+
+ sti
+ call main
+ cli
+
+ halt:
+ hlt
+ jmp halt
+