/* 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