aboutsummaryrefslogtreecommitdiff
path: root/i686/boot.s
diff options
context:
space:
mode:
Diffstat (limited to 'i686/boot.s')
-rw-r--r--i686/boot.s120
1 files changed, 120 insertions, 0 deletions
diff --git a/i686/boot.s b/i686/boot.s
new file mode 100644
index 0000000..40b0389
--- /dev/null
+++ b/i686/boot.s
@@ -0,0 +1,120 @@
+/* The magic field should contain this. */
+.set MULTIBOOT2_HEADER_MAGIC, 0xe85250d6
+/* This should be in %eax. */
+.set MULTIBOOT2_BOOTLOADER_MAGIC, 0x36d76289
+.set MULTIBOOT_ARCHITECTURE_I386, 0
+.set MULTIBOOT_HEADER_TAG_END, 0
+.set MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST, 1
+.set MULTIBOOT_TAG_TYPE_MMAP, 6
+
+.set PAGE_RO, 0x001
+.set PAGE_RW, 0x003
+
+/* write section to page table macro
+ *
+ * Registers used:
+ * %ecx: loop counter [ set to $1024 ]
+ * %edx: temporary
+ * %esi: current page being mapped
+ * %edi: page entry [ set to $page_addr ]
+ */
+.macro mmap_section begin, end, access
+ mov $\begin, %esi # from $begin
+1: cmpl $\end, %esi # until $end
+ jge 2f
+
+ movl %esi, %edx
+ orl $\access, %edx
+ movl %edx, (%edi)
+
+ addl $4096, %esi # move to next page
+ addl $4, %edi # size of page entry is 4 bytes
+ loop 1b # loop according to %ecx
+2:
+.endm
+
+/* 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
+