source: mainline/kernel/arch/ia32/src/boot/boot.S@ 71eef11

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 71eef11 was 71eef11, checked in by Martin Decky <martin@…>, 17 years ago

remove config.memory_size, get_memory_size() and memory_init.{c|d}
the amount of available memory can be calculated from the sizes of the zones
add FRAMES2SIZE, SIZE2KB and SIZE2MB functions/macros (code readability)

  • Property mode set to 100644
File size: 10.9 KB
RevLine 
[f761f1eb]1#
[df4ed85]2# Copyright (c) 2001-2004 Jakub Jermar
3# Copyright (c) 2005-2006 Martin Decky
[f761f1eb]4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9#
10# - Redistributions of source code must retain the above copyright
11# notice, this list of conditions and the following disclaimer.
12# - Redistributions in binary form must reproduce the above copyright
13# notice, this list of conditions and the following disclaimer in the
14# documentation and/or other materials provided with the distribution.
15# - The name of the author may not be used to endorse or promote products
16# derived from this software without specific prior written permission.
17#
18# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28#
29
[f9447155]30#include <arch/boot/boot.h>
[aa72859]31#include <arch/boot/memmap.h>
[8f2153b]32#include <arch/mm/page.h>
33#include <arch/pm.h>
[f9447155]34
[66def8d]35#define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE)
36
[874e312a]37.section K_TEXT_START, "ax"
[f761f1eb]38
[b0bf501]39.code32
[f9447155]40.align 4
[66def8d]41.global multiboot_image_start
[f9447155]42multiboot_header:
43 .long MULTIBOOT_HEADER_MAGIC
44 .long MULTIBOOT_HEADER_FLAGS
45 .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) # checksum
[66def8d]46 .long multiboot_header
47 .long unmapped_ktext_start
[f9447155]48 .long 0
49 .long 0
[66def8d]50 .long multiboot_image_start
[5dce48b9]51
[f9447155]52multiboot_image_start:
[66def8d]53 movl $START_STACK, %esp # initialize stack pointer
54 lgdt KA2PA(bootstrap_gdtr) # initialize Global Descriptor Table register
[b0bf501]55
[f476e76]56 movw $selector(KDATA_DES), %cx
[5eb1379]57 movw %cx, %es
58 movw %cx, %fs
[ff133e2]59 movw %cx, %gs
[66def8d]60 movw %cx, %ds # kernel data + stack
[5eb1379]61 movw %cx, %ss
[5dce48b9]62
[f476e76]63 jmpl $selector(KTEXT_DES), $multiboot_meeting_point
[4533601]64 multiboot_meeting_point:
65
[7cb567cd]66 movl %eax, grub_eax # save parameters from GRUB
67 movl %ebx, grub_ebx
[ff133e2]68
[eaf6cd6]69 xorl %eax, %eax
70 cpuid
71 cmp $0x0, %eax # any function > 0?
72 jbe pse_unsupported
[328f324b]73 movl $0x1, %eax # Basic function code 1
[eaf6cd6]74 cpuid
75 bt $3, %edx # Test if PSE is supported
76 jc pse_supported
77
78 pse_unsupported:
79 movl $pse_msg, %esi
80 jmp error_halt
81
82 pse_supported:
83
[22cf454d]84#ifdef CONFIG_FB
[ff133e2]85 mov $vesa_init, %esi
86 mov $VESA_INIT_SEGMENT << 4, %edi
87 mov $e_vesa_init - vesa_init, %ecx
88 cld
89 rep movsb
[22cf454d]90
[ff133e2]91 mov $VESA_INIT_SEGMENT << 4, %edi
[b3f8fb7]92 jmpl *%edi
[ff133e2]93
94 vesa_meeting_point:
95
96 mov %esi, KA2PA(vesa_ph_addr)
97 mov %di, KA2PA(vesa_height)
98 shr $16, %edi
99 mov %di, KA2PA(vesa_width)
100 mov %bx, KA2PA(vesa_scanline)
101 shr $16, %ebx
102 mov %bx, KA2PA(vesa_bpp)
[22cf454d]103#endif
[5eb1379]104
[b0edf3b2]105 call map_kernel # map kernel and turn paging on
[5dce48b9]106
[7cb567cd]107 movl grub_eax, %eax
108 movl grub_ebx, %ebx
[b0edf3b2]109 cmpl $MULTIBOOT_LOADER_MAGIC, %eax # compare GRUB signature
[5eb1379]110 je valid_boot
[339e053]111
[71eef11]112 xorl %ecx, %ecx # no memory map available
[339e053]113 movl %ecx, e820counter
[5eb1379]114
115 jmp invalid_boot
[339e053]116
[5eb1379]117 valid_boot:
118
[339e053]119 movl (%ebx), %eax # ebx = physical address of struct multiboot_info
[5eb1379]120
[b6b576c]121 bt $3, %eax # mbi->flags[3] (mods_count, mods_addr valid)
[aa72859]122 jc mods_valid
123
124 xorl %ecx, %ecx
[b6b576c]125 movl %ecx, init
126 jmp mods_end
[aa72859]127
128 mods_valid:
[b6b576c]129
[6c68b97]130 movl 20(%ebx), %ecx # mbi->mods_count
[b6b576c]131 movl %ecx, init
132
[6c68b97]133 cmpl $0, %ecx
[b6b576c]134 je mods_end
[6c68b97]135
136 movl 24(%ebx), %esi # mbi->mods_addr
[b6b576c]137 movl $init, %edi
138
139 mods_loop:
140
141 movl 0(%esi), %edx # mods->mod_start
142 addl $0x80000000, %edx
143 movl %edx, 4(%edi)
144
145 movl 4(%esi), %edx
146 subl 0(%esi), %edx # mods->mod_end - mods->mod_start
147 movl %edx, 8(%edi)
148
149 addl $16, %esi
150 addl $8 , %edi
151
152 loop mods_loop
153
154 mods_end:
[aa72859]155
[339e053]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
167
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
[5eb1379]199
200 invalid_boot:
201
[66def8d]202#ifdef CONFIG_SMP
203
204 # copy AP bootstrap routines below 1 MB
205
206 movl $BOOT_OFFSET, %esi
207 movl $AP_BOOT_OFFSET, %edi
208 movl $_hardcoded_unmapped_size, %ecx
209 cld
210 rep movsb
211
212#endif
[eaf6cd6]213
[66def8d]214 call main_bsp # never returns
[d47f0e1]215
216 cli
217 hlt
218
219.global map_kernel
220map_kernel:
[dcbc8be]221 #
222 # Here we setup mapping for both the unmapped and mapped sections of the kernel.
[cf27a6cb]223 # For simplicity, we map the entire 4G space.
[dcbc8be]224 #
225 movl %cr4, %ecx
[eaf6cd6]226 orl $(1 << 4), %ecx # turn PSE on
227 andl $(~(1 << 5)), %ecx # turn PAE off
228 movl %ecx, %cr4
[dcbc8be]229
[eaf6cd6]230 movl $(page_directory + 0), %esi
231 movl $(page_directory + 2048), %edi
[cf27a6cb]232 xorl %ecx, %ecx
233 xorl %ebx, %ebx
2340:
[eaf6cd6]235 movl $((1 << 7) | (1 << 1) | (1 << 0)), %eax
[cf27a6cb]236 orl %ebx, %eax
[eaf6cd6]237 movl %eax, (%esi, %ecx, 4) # mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M
238 movl %eax, (%edi, %ecx, 4) # mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M
239 addl $(4 * 1024 * 1024), %ebx
[dcbc8be]240
[cf27a6cb]241 incl %ecx
242 cmpl $512, %ecx
243 jl 0b
[dcbc8be]244
[cf27a6cb]245 movl %esi, %cr3
[f761f1eb]246
[dcbc8be]247 movl %cr0, %ebx
[eaf6cd6]248 orl $(1 << 31), %ebx # turn paging on
[dcbc8be]249 movl %ebx, %cr0
[d47f0e1]250 ret
[dcbc8be]251
[eaf6cd6]252# Print string from %esi to EGA display (in red) and halt
253error_halt:
254 movl $0xb8000, %edi # base of EGA text mode memory
255 xorl %eax, %eax
256
257 movw $0x3d4, %dx # read bits 8 - 15 of the cursor address
258 movb $0xe, %al
259 outb %al, %dx
260
261 movw $0x3d5, %dx
262 inb %dx, %al
263 shl $8, %ax
264
265 movw $0x3d4, %dx # read bits 0 - 7 of the cursor address
266 movb $0xf, %al
267 outb %al, %dx
268
269 movw $0x3d5, %dx
270 inb %dx, %al
271
272 cmp $1920, %ax
273 jbe cursor_ok
274 movw $1920, %ax # sanity check for the cursor on the last line
275 cursor_ok:
276
277 movw %ax, %bx
278 shl $1, %eax
279 addl %eax, %edi
280
281 movw $0x0c00, %ax # black background, light red foreground
282 cld
283
284 ploop:
285 lodsb
286 cmp $0, %al
287 je ploop_end
288 stosw
289 inc %bx
290 jmp ploop
291 ploop_end:
292
293 movw $0x3d4, %dx # write bits 8 - 15 of the cursor address
294 movb $0xe, %al
295 outb %al, %dx
296
297 movw $0x3d5, %dx
298 movb %bh, %al
299 outb %al, %dx
300
301 movw $0x3d4, %dx # write bits 0 - 7 of the cursor address
302 movb $0xf, %al
303 outb %al, %dx
304
305 movw $0x3d5, %dx
306 movb %bl, %al
307 outb %al, %dx
308
309 cli
310 hlt
311
[22cf454d]312#ifdef CONFIG_FB
313vesa_init:
[ff133e2]314 jmp $selector(VESA_INIT_DES), $vesa_init_real - vesa_init
315
[22cf454d]316.code16
[ff133e2]317vesa_init_real:
318
319 mov %cr0, %eax
320 and $~1, %eax
321 mov %eax, %cr0
322
323 jmp $VESA_INIT_SEGMENT, $vesa_init_real2 - vesa_init
324
325vesa_init_real2:
326
327 mov $VESA_INIT_SEGMENT, %bx
328
329 mov %bx, %es
330 mov %bx, %fs
331 mov %bx, %gs
332 mov %bx, %ds
333 mov %bx, %ss
334
335 movl %esp, %eax
336 movl $0x0000fffc, %esp
337 movl $0x0000fffc, %ebp
338 pushl %eax
[22cf454d]339
340#define VESA_INFO_SIZE 1024
341
[4f42d52]342#define VESA_MODE_ATTRIBUTES_OFFSET 0
[ff133e2]343#define VESA_MODE_LIST_PTR_OFFSET 14
[4f42d52]344#define VESA_MODE_SCANLINE_OFFSET 16
[22cf454d]345#define VESA_MODE_WIDTH_OFFSET 18
346#define VESA_MODE_HEIGHT_OFFSET 20
347#define VESA_MODE_BPP_OFFSET 25
348#define VESA_MODE_PHADDR_OFFSET 40
349
[ff133e2]350#define VESA_END_OF_MODES 0xffff
[22cf454d]351
[ff133e2]352#define VESA_OK 0x4f
[22cf454d]353
[ff133e2]354#define VESA_GET_INFO 0x4f00
[22cf454d]355#define VESA_GET_MODE_INFO 0x4f01
356#define VESA_SET_MODE 0x4f02
[4f42d52]357#define VESA_SET_PALETTE 0x4f09
[22cf454d]358
[ff133e2]359#if CONFIG_VESA_BPP == 24
[4f42d52]360#define CONFIG_VESA_BPP_VARIANT 32
[22cf454d]361#endif
362
[ff133e2]363 mov $VESA_GET_INFO, %ax
364 mov $e_vesa_init - vesa_init, %di
365 push %di
366 int $0x10
367
368 pop %di
369 cmp $VESA_OK, %al
370 jnz 0f
371
372 mov 2 + VESA_MODE_LIST_PTR_OFFSET(%di), %si
373 mov %si, %gs
374 mov VESA_MODE_LIST_PTR_OFFSET(%di), %si
375
376 add $VESA_INFO_SIZE, %di
[22cf454d]377
3781:# Try next mode
[ff133e2]379 mov %gs:(%si), %cx
380 cmp $VESA_END_OF_MODES, %cx
381 jz 0f
382
383 inc %si
384 inc %si
385 push %cx
386 push %di
387 push %si
388 mov $VESA_GET_MODE_INFO, %ax
389 int $0x10
390
391 pop %si
392 pop %di
393 pop %cx
394 cmp $VESA_OK, %al
395 jnz 0f
396
397 mov $CONFIG_VESA_WIDTH, %ax
398 cmp VESA_MODE_WIDTH_OFFSET(%di), %ax
399 jnz 1b
400
[4f42d52]401 mov $CONFIG_VESA_HEIGHT, %ax
[ff133e2]402 cmp VESA_MODE_HEIGHT_OFFSET(%di), %ax
403 jnz 1b
404
405 mov $CONFIG_VESA_BPP, %al
406 cmp VESA_MODE_BPP_OFFSET(%di), %al
[4f42d52]407
408#ifdef CONFIG_VESA_BPP_VARIANT
[ff133e2]409 jz 2f
410
[4f42d52]411 mov $CONFIG_VESA_BPP_VARIANT, %al
[ff133e2]412 cmp VESA_MODE_BPP_OFFSET(%di), %al
[4f42d52]413#endif
[ff133e2]414 jnz 1b
[4f42d52]415
[22cf454d]4162:
417
[ff133e2]418 mov %cx, %bx
419 or $0xc000, %bx
420 push %di
421 mov $VESA_SET_MODE, %ax
422 int $0x10
423
424 pop %di
425 cmp $VESA_OK, %al
426 jnz 0f
[4f42d52]427
428#if CONFIG_VESA_BPP == 8
429
430 # Set 3:2:3 VGA palette
431
432 mov VESA_MODE_ATTRIBUTES_OFFSET(%di), %ax
433 push %di
434 mov $vga323 - vesa_init, %di
435 mov $0x100, %ecx
436
437 bt $5, %ax # Test if VGA compatible registers are present
438 jnc vga_compat
439
440 # Try VESA routine to set palette
441
442 mov $VESA_SET_PALETTE, %ax
443 xor %bl, %bl
444 xor %dx, %dx
445 int $0x10
446
447 jmp vga_not_compat
448
449 vga_compat:
450
451 # Try VGA registers to set palette
452
453 movw $0x3c6, %dx # Set palette mask
454 movb $0xff, %al
455 outb %al, %dx
456
457 movw $0x3c8, %dx # First index to set
458 xor %al, %al
459 outb %al, %dx
460
461 movw $0x3c9, %dx # Data port
462 vga_loop:
463 movb %es:2(%di), %al
464 outb %al, %dx
465
466 movb %es:1(%di), %al
467 outb %al, %dx
468
469 movb %es:(%di), %al
470 outb %al, %dx
471
472 addw $4, %di
473 loop vga_loop
474
475 vga_not_compat:
476
477 pop %di
478
479#endif
[ff133e2]480
481 mov VESA_MODE_PHADDR_OFFSET(%di), %esi
482 mov VESA_MODE_WIDTH_OFFSET(%di), %ax
483 shl $16, %eax
484 mov VESA_MODE_HEIGHT_OFFSET(%di), %ax
485 mov VESA_MODE_BPP_OFFSET(%di), %bl
486 xor %bh, %bh
487 shl $16, %ebx
488 mov VESA_MODE_SCANLINE_OFFSET(%di), %bx
489 mov %eax, %edi
[22cf454d]490
4918:
[ff133e2]492
493 mov %cr0, %eax
494 or $1, %eax
[8778271]495 mov %eax, %cr0
[ff133e2]496
497 jmp 9f
[22cf454d]4989:
[ff133e2]499
[f476e76]500 ljmpl $selector(KTEXT_DES), $(vesa_init_protect - vesa_init + VESA_INIT_SEGMENT << 4)
[ff133e2]501
5020:# No prefered mode found
503 mov $0x111, %cx
504 push %di
505 push %cx
506 mov $VESA_GET_MODE_INFO, %ax
507 int $0x10
508
509 pop %cx
510 pop %di
511 cmp $VESA_OK, %al
512 jnz 1f
513 jz 2b # Force relative jump
514
5151:
516 mov $0x0003, %ax
517 int $0x10
518 mov $0xffffffff, %edi # EGA text mode used, because of problems with VESA
519 xor %ax, %ax
520 jz 8b # Force relative jump
[4f42d52]521
522vga323:
523#include "vga323.pal"
[22cf454d]524
[203dcd45]525.code32
[ff133e2]526vesa_init_protect:
[f476e76]527 movw $selector(KDATA_DES), %cx
[ff133e2]528 movw %cx, %es
529 movw %cx, %fs
530 movw %cx, %gs
531 movw %cx, %ds # kernel data + stack
532 movw %cx, %ss
533
[7cb567cd]534 movl $START_STACK, %esp # initialize stack pointer
535
[f476e76]536 jmpl $selector(KTEXT_DES), $vesa_meeting_point
[22cf454d]537
538.align 4
539e_vesa_init:
540#endif
541
[874e312a]542.section K_DATA_START, "aw", @progbits
[dcbc8be]543
544.align 4096
545page_directory:
546 .space 4096, 0
[eaf6cd6]547
[7cb567cd]548grub_eax:
549 .long 0
550
551grub_ebx:
552 .long 0
553
[eaf6cd6]554pse_msg:
[4f42d52]555 .asciz "Page Size Extension not supported. System halted."
Note: See TracBrowser for help on using the repository browser.