aboutsummaryrefslogtreecommitdiff
path: root/arch/i386/init.s
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/init.s')
-rw-r--r--arch/i386/init.s49
1 files changed, 49 insertions, 0 deletions
diff --git a/arch/i386/init.s b/arch/i386/init.s
new file mode 100644
index 0000000..ad329bb
--- /dev/null
+++ b/arch/i386/init.s
@@ -0,0 +1,49 @@
+.section .stack, "aw", @nobits
+.global k_stack
+.align 16 /* Stack on x86 must be 16-byte aligned according to System V ABI */
+k_stack_bottom:
+ .skip 16 * 1024 /* 16 kByte */
+k_stack:
+
+.section .pages, "aw", @nobits
+.align 4096
+.global k_pagedir
+k_pagedir: .skip 1024 * 4
+.global k_ptable0x300
+k_ptable0x300: .skip 1024 * 4
+
+.section .text
+.global k_init
+.extern kmain
+.extern gdt_install
+.extern idt_install
+k_init:
+ # kernel entry point, higher half
+
+ # unmap the identity mapping as its no longer necessary
+ movl $0, k_pagedir + 0 * 4
+ mov %cr3, %ecx # reload cr3 to force a TLB flush
+ mov %ecx, %cr3
+
+ # zero out the stack
+ mov $4096, %ecx # loop counter
+ mov $k_stack_bottom, %edi # start from the bottom
+ xor %edx, %edx # clear %edx
+1: movl %edx, (%edi) # store %edx into address in %edi
+ addl $4, %edi # point to next address
+ loop 1b # loop according to %ecx
+
+ mov $k_stack, %esp # point stack pointer to the stack
+
+ # hardware init
+ call gdt_install # Global Descriptor Table
+ call idt_install # Interrupt Descriptor Table
+
+ # jump into kernel
+ call kmain
+
+ /* If the system has nothing more to do, put it in an infinite loop */
+ cli # disable interrupts
+h: hlt # wait for interrupt
+ jmp h # continue waiting for interrupt
+