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
110
111
112
113
114
115
116
117
118
119
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
|