-
Notifications
You must be signed in to change notification settings - Fork 4
/
boot.s
109 lines (92 loc) · 2.6 KB
/
boot.s
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# Source: http://wiki.osdev.org/Bare_Bones
.set ALIGN, 1<<0 # align loaded modules on page boundaries
.set MEMINFO, 1<<1 # provide memory map
.set FLAGS, ALIGN | MEMINFO # this is the Multiboot 'flag' field
.set MAGIC, 0x1BADB002 # 'magic number' lets bootloader find the header
.set CHECKSUM, -(MAGIC + FLAGS) # checksum of above, to prove we are multiboot
.section .multiboot
.align 4
.long MAGIC
.long FLAGS
.long CHECKSUM
.set KERNEL_VIRTUAL_BASE, 0xc0000000
.set KERNEL_PAGE_NUMBER, (KERNEL_VIRTUAL_BASE >> 22)
.section .bootstrap_stack, "aw", @nobits
stack_bottom:
.skip 16384 # 16 KiB
.global stack_top
stack_top:
.section .data
.align 0x1000
_boot_page_directory:
# identity map the first 4 MB
.long 0x00000083
# no pages until upper half
.rept (KERNEL_PAGE_NUMBER - 1)
.long 0
.endr
# upper half will be fully mapped to lower half
.rept (1024 - KERNEL_PAGE_NUMBER)
.long 0
.endr
.global _kernel_virtual_base
_kernel_virtual_base:
.long KERNEL_VIRTUAL_BASE
.section .text
.align 4
.global _entrypoint
.type _entrypoint, @function
.set _entrypoint, (_start - KERNEL_VIRTUAL_BASE)
.global _start
.type _start, @function
_start:
# when _entrypoint is called, this is the only code running in 0x10000
# our job is to set up paging for the higher half, then call into
# kernel_main in the higher half
# note that %eax contains a Multiboot magic and %ebx contains a
# Multiboot information address, so don't clobber these registers
cli
# initialize page directory
mov $0x00000083, %edx
mov $(_boot_page_directory - KERNEL_VIRTUAL_BASE + KERNEL_PAGE_NUMBER * 4), %ecx
mov $(1024 - KERNEL_PAGE_NUMBER), %ebp
# map only 32 pages
#mov $32, %ebp
l1:
movl %edx, (%ecx)
add $0x00400000, %edx
add $4, %ecx
dec %ebp
jnz l1
mov $(_boot_page_directory - KERNEL_VIRTUAL_BASE), %ecx
mov %ecx, %cr3
# enable 4 mb pages
mov %cr4, %ecx
or $0x00000010, %ecx
mov %ecx, %cr4
# enable paging
mov %cr0, %ecx
or $0x80000000, %ecx
mov %ecx, %cr0
lea [higher_half], %ecx
jmp *%ecx
higher_half:
# Unmap the identity-mapped pages
movl $0, _boot_page_directory
movl $stack_top, %esp
# Mark end of call stack for unwinding
movl $0, %ebp
# We expect a Multiboot boot, where %eax contains the Multiboot magic
# and %ebx a pointer to a struct with hardware information in physical
# memory. These, along with the symbol pointing to the end of the
# memory used for the kernel binary, are passed as parameters to the
# kernel_main function.
add $KERNEL_VIRTUAL_BASE, %ebx
push $__end_of_binary
push %ebx
push %eax
call kernel_main
hlt
.Lhang:
jmp .Lhang
.size _start, . - _start