aboutsummaryrefslogtreecommitdiff
path: root/arch/i686/boot.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i686/boot.S')
-rw-r--r--arch/i686/boot.S89
1 files changed, 89 insertions, 0 deletions
diff --git a/arch/i686/boot.S b/arch/i686/boot.S
new file mode 100644
index 0000000..1eea9a3
--- /dev/null
+++ b/arch/i686/boot.S
@@ -0,0 +1,89 @@
+#define ASM_FILE
+#include <multiboot2.h>
+#include "macros.s"
+
+/* Declare a multiboot header that marks this program as a kernel */
+.section .multiboot.header, "a"
+header_begin:
+.align 8
+ .int MULTIBOOT2_HEADER_MAGIC
+ .int MULTIBOOT_ARCHITECTURE_I386
+ .int header_end - header_begin
+ .int -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE_I386 + (header_end - header_begin))
+
+.align 8
+header_info_begin:
+ .short MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST
+ .short 0 # flags
+ .int header_info_end - header_info_begin
+ .int MULTIBOOT_TAG_TYPE_MMAP
+header_info_end:
+
+.align 8
+ .short MULTIBOOT_HEADER_TAG_END
+ .short 0
+ .int 8
+header_end:
+
+.section .multiboot.pages, "aw", @nobits
+.align 4096
+bootstrap_page0:
+ .skip 1024 * 4
+
+.section .multiboot.text, "ax"
+.extern k_pagedir
+.extern k_stack
+.extern k_init
+
+#.global __vaddr_base
+#.set __vaddr_base, 0xc0000000
+#.global __vaddr_offset
+.set __vaddr_offset, 0xc0000000 - 0x2000
+
+.global _start
+.type _start, @function
+_start:
+ cli
+
+ # check multiboot header
+ cmp $MULTIBOOT2_BOOTLOADER_MAGIC, %eax
+ jz c
+ hlt
+
+c: mov $k_stack - __vaddr_offset, %esp
+
+ push %ebx # pointer to multiboot structure
+ call __multiboot2
+
+ # mmap multiboot section into bootstrap page
+ movl $bootstrap_page0, %edi
+ movl $1024, %ecx
+ mmap_section __multiboot_begin, __multiboot_end, PAGE_RW
+ mmap_section (__text_begin - __vaddr_offset), (__text_end - __vaddr_offset), PAGE_RO
+ mmap_section (__rodata_begin - __vaddr_offset), (__rodata_end - __vaddr_offset), PAGE_RO
+ mmap_section (__bss_begin - __vaddr_offset), (__bss_end - __vaddr_offset), PAGE_RW
+ mmap_section (__data_begin - __vaddr_offset), (__data_end - __vaddr_offset), PAGE_RW
+
+ # mmap all the other section into k_ptable0x300
+ movl $(k_ptable0x300 - __vaddr_offset), %edi
+ movl $1024, %ecx
+ mmap_section (__text_begin - __vaddr_offset), (__text_end - __vaddr_offset), PAGE_RO
+ mmap_section (__rodata_begin - __vaddr_offset), (__rodata_end - __vaddr_offset), PAGE_RO
+ mmap_section (__bss_begin - __vaddr_offset), (__bss_end - __vaddr_offset), PAGE_RW
+ mmap_section (__data_begin - __vaddr_offset), (__data_end - __vaddr_offset), PAGE_RW
+
+ movl $(bootstrap_page0 + PAGE_RW), k_pagedir - __vaddr_offset + 0 * 4
+ movl $(k_ptable0x300 - __vaddr_offset + PAGE_RW), k_pagedir - __vaddr_offset + 768 * 4
+
+ movl $(k_pagedir - __vaddr_offset), %ecx
+ movl %ecx, %cr3
+
+ # enable paging and the write-protect bit
+ movl %cr0, %ecx
+ orl $0x80010000, %ecx
+ movl %ecx, %cr0
+
+ # jump to higher half with an absolute jump
+ lea (k_init), %ecx
+ jmp *%ecx
+