aboutsummaryrefslogtreecommitdiff
path: root/i686/boot.S
blob: 16d54a309bc976e3ecf758bcf133d4bde4a9a18d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#define ASM_FILE
#include <grub/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