Annotation of prex/boot/i386/pc/head.S, Revision 1.1
1.1 ! nbrk 1: /*-
! 2: * Copyright (c) 2005-2007, Kohsuke Ohtani
! 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: * 1. Redistributions of source code must retain the above copyright
! 9: * notice, this list of conditions and the following disclaimer.
! 10: * 2. Redistributions in binary form must reproduce the above copyright
! 11: * notice, this list of conditions and the following disclaimer in the
! 12: * documentation and/or other materials provided with the distribution.
! 13: * 3. Neither the name of the author nor the names of any co-contributors
! 14: * may be used to endorse or promote products derived from this software
! 15: * without specific prior written permission.
! 16: *
! 17: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
! 18: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 19: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 20: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
! 21: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 22: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 23: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 24: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 25: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 26: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 27: * SUCH DAMAGE.
! 28: */
! 29:
! 30: /*
! 31: * head.S - low level platform support
! 32: */
! 33:
! 34: #include <conf/config.h>
! 35: #include "platform.h"
! 36:
! 37: #define SCREEN_80x25 1
! 38: /* #define SCREEN_80x50 1 */
! 39:
! 40: #define SEL_CODE32 0x10
! 41: #define SEL_DATA32 0x18
! 42:
! 43: #define ENTRY(x) .global x; .align; x##:
! 44:
! 45: .text
! 46: .code16
! 47:
! 48: /*
! 49: * boot_entry - Entry point for prex boot loader
! 50: */
! 51: ENTRY(boot_entry)
! 52: cld
! 53: cli
! 54:
! 55: /*
! 56: * Relocate boot loader
! 57: */
! 58: movw %cs, %ax
! 59: movw %ax, %ds
! 60: xorw %si, %si
! 61: movw %si, %es
! 62: movw $0x4000, %di /* Relocation address 0:4000 */
! 63: movw $0x800, %cx /* size 0x2000 */
! 64: rep movsl
! 65: ljmp $0x0000, $(reset_cs)
! 66: reset_cs:
! 67:
! 68: movw %cs, %ax /* Reset segment registers */
! 69: movw %ax, %ds
! 70:
! 71: xorw %ax, %ax /* Reset stack */
! 72: movw %ax, %ss
! 73: movw $(BOOT_STACK+0x800), %sp
! 74:
! 75: call setup_screen
! 76: call get_memsize
! 77: cli /* Disable all interrupts */
! 78: call enable_a20 /* Enable A20 line */
! 79:
! 80: lgdt gdt_desc /* Load GDT */
! 81:
! 82: movl %cr0, %eax /* Switch to protected mode */
! 83: orl $0x1, %eax
! 84: movl %eax, %cr0
! 85:
! 86: .byte 0x66 /* 32-bit long jump to reset CS */
! 87: .byte 0xea
! 88: .long go_prot
! 89: .word SEL_CODE32
! 90: .code32
! 91: .align 4
! 92: go_prot:
! 93: movw $(SEL_DATA32), %ax /* Reset data segments */
! 94: movw %ax, %ds
! 95: movw %ax, %es
! 96: movw %ax, %ss
! 97: movw %ax, %fs
! 98: movw %ax, %gs
! 99: /*
! 100: * Relocate archive file
! 101: */
! 102: movl $(ARCHIVE_START), %edi /* Relocation target */
! 103: movl $0x32000, %esi
! 104: movl $0x1B800, %ecx /* size 0x6e000 */
! 105: rep movsl
! 106:
! 107: jmp loader_main /* Jump to main routine in C */
! 108:
! 109: /*
! 110: * get_memsize - Get memory size
! 111: */
! 112: .code16
! 113: get_memsize:
! 114: xorl %eax, %eax
! 115: int $0x12 /* Get conventional memory size */
! 116: movl %eax, lo_mem /* ax = K bytes */
! 117:
! 118: mov $0x88, %ah
! 119: int $0x15
! 120: andb $0xfc, %al /* Adjust to page boundary */
! 121: movl %eax, hi_mem /* ax = K bytes at 100000h */
! 122: ret
! 123:
! 124: /*
! 125: * enable_a20 - Enable A20
! 126: */
! 127: .code16
! 128: enable_a20:
! 129: call empty_8042
! 130: movb $0xd1, %al
! 131: outb %al, $0x64
! 132: call empty_8042
! 133: movb $0xdf, %al
! 134: outb %al, $0x60
! 135: call empty_8042
! 136: call wait_a20
! 137: ret
! 138:
! 139: /*
! 140: * empty_8042 - Empty 8042
! 141: */
! 142: empty_8042:
! 143: inb $0x64, %al
! 144: testb $0x01, %al
! 145: jz no_output
! 146: inb $0x60, %al
! 147: jmp empty_8042
! 148: no_output:
! 149: testb $0x02, %al
! 150: jnz empty_8042
! 151: ret
! 152:
! 153: /*
! 154: * wait_a20 - Wait A20 ready
! 155: */
! 156: wait_a20:
! 157: xorw %ax, %ax
! 158: movw %ax, %fs
! 159: movw $0xffff, %ax
! 160: movw %ax, %gs
! 161: movw %fs:(0x0), %ax
! 162: cmp %gs:(16), %ax
! 163: jne a20_ready
! 164: movw %dx, %ax
! 165: notw %ax
! 166: movw %ax, %fs:(0x0)
! 167: cmp %gs:(16), %ax
! 168: mov %fs:(0), %dx
! 169: jne a20_ready
! 170: jmp wait_a20
! 171: a20_ready:
! 172: ret
! 173:
! 174: /*
! 175: * Setup screen
! 176: */
! 177: setup_screen:
! 178: pushaw
! 179: pushw %es
! 180: pushw %ds
! 181: pushw %bp
! 182: movb $0x2e, %al /* print '.' for verify */
! 183: movb $0x0e, %ah
! 184: movw $0x07, %bx
! 185: int $0x10
! 186:
! 187: movw $0x3, %ax /* Use mode-3 */
! 188: int $0x10
! 189: movw $0x1202, %ax /* 400 scan lines */
! 190: movb $0x30, %bl
! 191: int $0x10
! 192: #if SCREEN_80x50
! 193: movw $0x1112, %ax /* Load 8x8 character set */
! 194: movb $0x0, %bl
! 195: int $0x10
! 196: movw $0x1201, %ax /* Turn off cursor emulation */
! 197: movb $0x34, %bl
! 198: int $0x10
! 199: movb $0x01, %ah /* Set cursor type */
! 200: movw $0x0607, %cx
! 201: int $0x10
! 202: #endif
! 203: popw %bp
! 204: popw %ds
! 205: popw %es
! 206: popaw
! 207: ret
! 208:
! 209: .code32
! 210: /*
! 211: * Start kernel
! 212: */
! 213: ENTRY(start_kernel)
! 214: movl 4(%esp), %eax
! 215: movl 8(%esp), %ebx /* Store multiboot information in EBX */
! 216: movl %eax, kern_start
! 217: jmp code_flush
! 218: code_flush:
! 219: /* Prepare registers for kernel */
! 220: movw $(SEL_DATA32), %ax
! 221: movw %ax, %ds
! 222: movw %ax, %es
! 223: movw %ax, %fs
! 224: movw %ax, %gs
! 225:
! 226: xorl %eax, %eax
! 227: movl %eax, %ecx
! 228: movl %eax, %edx
! 229: movl %eax, %esi
! 230: movl %eax, %edi
! 231:
! 232: movl $0x2BADB002, %eax /* Store multiboot magic in EAX */
! 233: cli
! 234:
! 235: .byte 0xea
! 236: kern_start:
! 237: .long 0
! 238: .word SEL_CODE32
! 239:
! 240: /*
! 241: * putchar - output to bochs emulater console.
! 242: */
! 243: ENTRY(putchar)
! 244: #if defined(DEBUG) && defined(CONFIG_DIAG_BOCHS)
! 245: inb $0xe9, %al
! 246: cmpb $0xe9, %al
! 247: jne no_bochs
! 248: movl 4(%esp), %eax
! 249: outb %al, $0xe9
! 250: no_bochs:
! 251: #endif
! 252: ret
! 253:
! 254:
! 255: /*
! 256: * machine_panic - panic handler
! 257: */
! 258: ENTRY(machine_panic)
! 259: stop:
! 260: jmp stop
! 261:
! 262: /*
! 263: * Data
! 264: */
! 265: .align 16
! 266: gdt:
! 267: .word 0x0,0x0,0x0,0x0 /* 0x00 - Null descritor */
! 268: .word 0x0,0x0,0x0,0x0 /* 0x08 - Null descritor */
! 269: .word 0xffff,0x0,0x9a00,0xcf /* 0x10 - 32 bit code segment */
! 270: .word 0xffff,0x0,0x9200,0xcf /* 0x18 - 32 bit data segment */
! 271: .word 0xffff,0x0,0x9a00,0x0 /* 0x20 - 16 bit code segment */
! 272: .word 0xffff,0x0,0x9200,0x0 /* 0x28 - 16 bit data segment */
! 273:
! 274: gdt_desc:
! 275: .word 0x2F /* limit */
! 276: .long gdt /* address */
! 277:
! 278: .word 0x0 /* alignment */
! 279: idt_desc:
! 280: .word 0x0
! 281: .long 0x0
! 282:
! 283: e820_buf:
! 284: .space 20
! 285:
! 286: .align 16
! 287: .global lo_mem, hi_mem
! 288: lo_mem:
! 289: .long 0x0
! 290: hi_mem:
! 291: .long 0x0
! 292:
! 293: /*
! 294: * Pad data
! 295: */
! 296: .section .tail,"a"
! 297: dummy:
! 298: .byte 0xff
CVSweb