Subversion Repositories HelenOS-historic

Rev

Rev 280 | Rev 298 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 jermar 1
#
2
# Copyright (C) 2001-2004 Jakub Jermar
3
# All rights reserved.
4
#
5
# Redistribution and use in source and binary forms, with or without
6
# modification, are permitted provided that the following conditions
7
# are met:
8
#
9
# - Redistributions of source code must retain the above copyright
10
#   notice, this list of conditions and the following disclaimer.
11
# - Redistributions in binary form must reproduce the above copyright
12
#   notice, this list of conditions and the following disclaimer in the
13
#   documentation and/or other materials provided with the distribution.
14
# - The name of the author may not be used to endorse or promote products
15
#   derived from this software without specific prior written permission.
16
#
17
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
#
28
 
222 decky 29
#include <arch/boot/boot.h>
285 decky 30
#include <arch/boot/memmapasm.h>
222 decky 31
 
1 jermar 32
.section K_TEXT_START
33
.global kernel_image_start
34
 
267 decky 35
KTEXT=8
36
KDATA=16
37
 
1 jermar 38
.code16
39
#
40
# This is where we require any SPARTAN-kernel-compatible boot loader
41
# to pass control in real mode.
42
#
43
# Protected mode tables are statically initialised during compile
44
# time. So we can just load the respective table registers and
45
# switch to protected mode.
46
#
47
kernel_image_start:
174 jermar 48
	cli
235 decky 49
	xorw %ax, %ax
50
	movw %ax, %ds
267 decky 51
	movw %ax, %ss							# initialize stack segment register
52
	movl $BOOTSTRAP_OFFSET - 0x400, %esp	# initialize stack pointer
176 jermar 53
 
54
	call memmap_arch_init
55
 
279 decky 56
	lgdt real_bootstrap_gdtr				# initialize Global Descriptor Table register
177 jermar 57
 
235 decky 58
	movl %cr0, %eax
59
	orl $0x1, %eax
267 decky 60
	movl %eax, %cr0							# switch to protected mode
235 decky 61
 
267 decky 62
	jmpl $KTEXT, $boot_image_start
235 decky 63
 
112 jermar 64
.code32
222 decky 65
.align 4
66
multiboot_header:
67
	.long MULTIBOOT_HEADER_MAGIC
68
	.long MULTIBOOT_HEADER_FLAGS
69
	.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)	# checksum
235 decky 70
	.long multiboot_header + BOOT_OFFSET
71
	.long unmapped_ktext_start + BOOT_OFFSET
222 decky 72
	.long 0
73
	.long 0
235 decky 74
	.long multiboot_image_start + BOOT_OFFSET
222 decky 75
 
235 decky 76
boot_image_start:
267 decky 77
	movw $KDATA, %ax
235 decky 78
	movw %ax, %es
79
	movw %ax, %gs
80
	movw %ax, %fs
81
	movw %ax, %ds			# kernel data + stack
82
	movw %ax, %ss
83
 
84
	movb $0xd1, %al			# enable A20 using the keyboard controller
85
	outb %al, $0x64
86
	movb $0xdf, %al
87
	outb %al, $0x60
88
 
267 decky 89
	movl $BOOTSTRAP_OFFSET, %esi
90
	movl $BOOTSTRAP_OFFSET + BOOT_OFFSET, %edi
235 decky 91
	movl $_hardcoded_kernel_size, %ecx
92
	cld
93
	rep movsb
94
 
285 decky 95
	call map_kernel			# map kernel and turn paging on
96
 
279 decky 97
	call main_bsp			# never returns
98
 
99
	cli
100
	hlt
235 decky 101
 
222 decky 102
multiboot_image_start:
279 decky 103
	movl $BOOTSTRAP_OFFSET - 0x400, %esp			# initialize stack pointer
222 decky 104
 
279 decky 105
	lgdt protected_bootstrap_gdtr - 0x80000000		# initialize Global Descriptor Table register
112 jermar 106
 
280 decky 107
	movw $KDATA, %cx
108
	movw %cx, %es
109
	movw %cx, %gs
110
	movw %cx, %fs
111
	movw %cx, %ds									# kernel data + stack
112
	movw %cx, %ss
235 decky 113
 
279 decky 114
	jmpl $KTEXT, $multiboot_meeting_point + BOOT_OFFSET
271 decky 115
	multiboot_meeting_point:
116
 
285 decky 117
	pushl %ebx										# save parameters from GRUB
280 decky 118
	pushl %eax
119
 
285 decky 120
	movl $BOOTSTRAP_OFFSET + BOOT_OFFSET, %esi
121
	movl $BOOTSTRAP_OFFSET, %edi
122
	movl $_hardcoded_unmapped_size, %ecx
123
	cld
124
	rep movsb
125
 
279 decky 126
	call map_kernel									# map kernel and turn paging on
235 decky 127
 
280 decky 128
	popl %eax
129
	popl %ebx
285 decky 130
	cmpl $MULTIBOOT_LOADER_MAGIC, %eax			# compare GRUB signature
280 decky 131
	je valid_boot
132
 
285 decky 133
		xorl %ecx, %ecx							# no memory size or map available
134
		movl %ecx, e801memorysize
135
		movl %ecx, e820counter
136
 
280 decky 137
		jmp invalid_boot
285 decky 138
 
280 decky 139
	valid_boot:
140
 
285 decky 141
		movl (%ebx), %eax						# ebx = physical address of struct multiboot_info
280 decky 142
 
285 decky 143
		bt $0, %eax								# mbi->flags[0] (mem_lower, mem_upper valid)
144
		jc mem_valid
145
 
146
			xorl %ecx, %ecx
147
			jmp mem_invalid
148
 
149
		mem_valid:
150
		movl 4(%ebx), %ecx						# mbi->mem_lower
151
		addl 8(%ebx), %ecx						# mbi->mem_upper
280 decky 152
 
285 decky 153
		mem_invalid:
280 decky 154
		movl %ecx, e801memorysize
155
 
285 decky 156
		bt $6, %eax								# mbi->flags[6] (mmap_length, mmap_addr valid)	
157
		jc mmap_valid
158
 
159
			xorl %edx, %edx
160
			jmp mmap_invalid
161
 
162
		mmap_valid:
163
		movl 44(%ebx), %ecx						# mbi->mmap_length
164
		movl 48(%ebx), %esi						# mbi->mmap_addr
165
		movl $e820table, %edi
166
		xorl %edx, %edx
280 decky 167
 
285 decky 168
		mmap_loop:
169
			cmpl $0, %ecx
170
			jle mmap_end
171
 
172
			movl 4(%esi), %eax					# mmap->base_addr_low
173
			movl %eax, (%edi)
174
 
175
			movl 8(%esi), %eax					# mmap->base_addr_high
176
			movl %eax, 4(%edi)
177
 
178
			movl 12(%esi), %eax					# mmap->length_low
179
			movl %eax, 8(%edi)
180
 
181
			movl 16(%esi), %eax					# mmap->length_high
182
			movl %eax, 12(%edi)
183
 
184
			movl 20(%esi), %eax					# mmap->type
185
			movl %eax, 16(%edi)
186
 
187
			movl (%esi), %eax					# mmap->size
188
			addl $0x4, %eax
189
			addl %eax, %esi
190
			subl %eax, %ecx
191
			addl $MEMMAP_E820_RECORD_SIZE, %edi
192
			incl %edx
193
			jmp mmap_loop
194
 
195
		mmap_end:
196
 
197
		mmap_invalid:
198
		movl %edx, e820counter
199
 
280 decky 200
	invalid_boot:
201
 
279 decky 202
	call main_bsp - BOOT_OFFSET						# never returns
110 jermar 203
 
204
	cli
205
	hlt
206
 
207
.global map_kernel
208
map_kernel:
105 jermar 209
	#
210
	# Here we setup mapping for both the unmapped and mapped sections of the kernel.
211
	# For simplicity, we set only one 4M page for 0x00000000 and one for 0x80000000.
212
	#
213
	movl %cr4, %ecx
214
	orl $(1<<4), %ecx
215
	movl %ecx, %cr4				# turn PSE on
1 jermar 216
 
105 jermar 217
	movl $((1<<7)|(1<<0)), %eax
218
	movl %eax, page_directory		# mapping 0x00000000 => 0x00000000
1 jermar 219
 
105 jermar 220
	movl $(page_directory+(4096/2)), %edx
221
	movl %eax, (%edx)			# mapping 0x80000000 => 0x00000000
222
 
223
	leal page_directory, %eax
224
	movl %eax, %cr3
225
 
177 jermar 226
	# turn paging on
105 jermar 227
	movl %cr0, %ebx
228
	orl $(1<<31), %ebx
229
	movl %ebx, %cr0
110 jermar 230
	ret
105 jermar 231
 
232
 
233
.section K_DATA_START
234
 
235
.align 4096
236
page_directory:
237
	.space 4096, 0