/*- * Copyright (c) 2005-2007, Kohsuke Ohtani * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * head.S - low level platform support */ #include #include "platform.h" #define SCREEN_80x25 1 /* #define SCREEN_80x50 1 */ #define SEL_CODE32 0x10 #define SEL_DATA32 0x18 #define ENTRY(x) .global x; .align; x##: .text .code16 /* * boot_entry - Entry point for prex boot loader */ ENTRY(boot_entry) cld cli /* * Relocate boot loader */ movw %cs, %ax movw %ax, %ds xorw %si, %si movw %si, %es movw $0x4000, %di /* Relocation address 0:4000 */ movw $0x800, %cx /* size 0x2000 */ rep movsl ljmp $0x0000, $(reset_cs) reset_cs: movw %cs, %ax /* Reset segment registers */ movw %ax, %ds xorw %ax, %ax /* Reset stack */ movw %ax, %ss movw $(BOOT_STACK+0x800), %sp call setup_screen call get_memsize cli /* Disable all interrupts */ call enable_a20 /* Enable A20 line */ lgdt gdt_desc /* Load GDT */ movl %cr0, %eax /* Switch to protected mode */ orl $0x1, %eax movl %eax, %cr0 .byte 0x66 /* 32-bit long jump to reset CS */ .byte 0xea .long go_prot .word SEL_CODE32 .code32 .align 4 go_prot: movw $(SEL_DATA32), %ax /* Reset data segments */ movw %ax, %ds movw %ax, %es movw %ax, %ss movw %ax, %fs movw %ax, %gs /* * Relocate archive file */ movl $(ARCHIVE_START), %edi /* Relocation target */ movl $0x32000, %esi movl $0x1B8000, %ecx /* size 0x6e000 */ rep movsl jmp loader_main /* Jump to main routine in C */ /* * get_memsize - Get memory size */ .code16 get_memsize: xorl %eax, %eax int $0x12 /* Get conventional memory size */ movl %eax, lo_mem /* ax = K bytes */ mov $0x88, %ah int $0x15 andb $0xfc, %al /* Adjust to page boundary */ movl %eax, hi_mem /* ax = K bytes at 100000h */ ret /* * enable_a20 - Enable A20 */ .code16 enable_a20: call empty_8042 movb $0xd1, %al outb %al, $0x64 call empty_8042 movb $0xdf, %al outb %al, $0x60 call empty_8042 wait_enable: ret /* * empty_8042 - Empty 8042 */ empty_8042: pushw %ax retry: call io_delay inb $0x64, %al testb $1, %al jz no_output call io_delay inb $0x60, %al jmp retry no_output: testb $2, %al jnz retry popw %ax ret /* * io_delay - I/O delay */ io_delay: pushw %ax inb $0x80, %al inb $0x80, %al popw %ax ret /* * Setup screen */ setup_screen: pushaw pushw %es pushw %ds pushw %bp movb $0x2e, %al /* print '.' for verify */ movb $0x0e, %ah movw $0x07, %bx int $0x10 movw $0x3, %ax /* Use mode-3 */ int $0x10 movw $0x1202, %ax /* 400 scan lines */ movb $0x30, %bl int $0x10 #if SCREEN_80x50 movw $0x1112, %ax /* Load 8x8 character set */ movb $0x0, %bl int $0x10 movw $0x1201, %ax /* Turn off cursor emulation */ movb $0x34, %bl int $0x10 movb $0x01, %ah /* Set cursor type */ movw $0x0607, %cx int $0x10 #endif popw %bp popw %ds popw %es popaw ret .code32 /* * Start kernel */ ENTRY(start_kernel) movl 4(%esp), %eax movl 8(%esp), %ebx /* Store multiboot information in EBX */ movl %eax, kern_start jmp code_flush code_flush: /* Prepare registers for kernel */ movw $(SEL_DATA32), %ax movw %ax, %ds movw %ax, %es movw %ax, %fs movw %ax, %gs xorl %eax, %eax movl %eax, %ecx movl %eax, %edx movl %eax, %esi movl %eax, %edi movl $0x2BADB002, %eax /* Store multiboot magic in EAX */ cli .byte 0xea kern_start: .long 0 .word SEL_CODE32 /* * Data */ .align 16 gdt: .word 0x0,0x0,0x0,0x0 /* 0x00 - Null descritor */ .word 0x0,0x0,0x0,0x0 /* 0x08 - Null descritor */ .word 0xffff,0x0,0x9a00,0xcf /* 0x10 - 32 bit code segment */ .word 0xffff,0x0,0x9200,0xcf /* 0x18 - 32 bit data segment */ .word 0xffff,0x0,0x9a00,0x0 /* 0x20 - 16 bit code segment */ .word 0xffff,0x0,0x9200,0x0 /* 0x28 - 16 bit data segment */ gdt_desc: .word 0x2F /* limit */ .long gdt /* address */ .word 0x0 /* alignment */ idt_desc: .word 0x0 .long 0x0 e820_buf: .space 20 .align 16 .global lo_mem, hi_mem lo_mem: .long 0x0 hi_mem: .long 0x0 /* * Pad data */ .section .tail,"a" dummy: .byte 0xff