diff options
Diffstat (limited to 'i686/boot.S')
-rw-r--r-- | i686/boot.S | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/i686/boot.S b/i686/boot.S new file mode 100644 index 0000000..1eea9a3 --- /dev/null +++ b/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 + |