gptldr.S revision 172940
1/*- 2 * Copyright (c) 2007 Yahoo!, Inc. 3 * All rights reserved. 4 * Written by: John Baldwin <jhb@FreeBSD.org> 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 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. 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 * 3. Neither the name of the author nor the names of any co-contributors 15 * may be used to endorse or promote products derived from this software 16 * without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 * $FreeBSD: head/sys/boot/i386/gptboot/gptldr.S 172940 2007-10-24 21:33:00Z jhb $ 31 */ 32 33/* Memory Locations */ 34 .set MEM_REL,0x700 # Relocation address 35 .set MEM_ARG,0x900 # Arguments 36 .set MEM_ORG,0x7c00 # Origin 37 .set MEM_BUF,0x8cec # Load area 38 .set MEM_BTX,0x9000 # BTX start 39 .set MEM_JMP,0x9010 # BTX entry point 40 .set MEM_USR,0xa000 # Client start 41 .set BDA_BOOT,0x472 # Boot howto flag 42 43/* Misc. Constants */ 44 .set SIZ_PAG,0x1000 # Page size 45 .set SIZ_SEC,0x200 # Sector size 46 47 .globl start 48 .code16 49 50/* 51 * Copy BTX and boot2 to the right locations and start it all up. 52 */ 53 54/* 55 * Setup the segment registers to flat addressing (segment 0) and setup the 56 * stack to end just below the start of our code. 57 */ 58start: xor %cx,%cx # Zero 59 mov %cx,%es # Address 60 mov %cx,%ds # data 61 mov %cx,%ss # Set up 62 mov $start,%sp # stack 63 64/* 65 * BTX is right after us at 'end'. We read the length of BTX out of 66 * its header to find boot2. We need to copy boot2 to MEM_USR and BTX 67 * to MEM_BTX. Since those might overlap, we have to copy boot2 68 * backwards first and then copy BTX. We aren't sure exactly how long 69 * boot2 is, but we assume it can't be longer than 64k, so we just always 70 * copy 64k. 71 */ 72 mov $end,%bx # BTX 73 mov 0xa(%bx),%si # Get BTX length and set 74 add %bx,%si # %si to start of boot2 75 mov %si,%ax # Align %ds:%si on a 76 shr $4,%ax # paragraph boundary 77 and $0xf,%si # with the smallest 78 mov %ax,%ds # possible %si 79 add $(64 * 1024 - 16),%si 80 mov $MEM_USR/16,%ax # Point %es:%di at end of 81 mov $(64 * 1024 - 16),%di # largest boot2 range 82 mov %ax,%es 83 std 84 mov %di,%cx # Copy 64k - paragraph + 1 85 inc %cx # bytes 86 rep movsb 87 mov %cx,%ds # Reset %ds and %es 88 mov %cx,%es 89 mov 0xa(%bx),%cx # Get BTX length and set 90 mov %bx,%si # %si to end of BTX 91 mov $MEM_BTX,%di # %di -> end of BTX at 92 add %cx,%si # MEM_BTX 93 add %cx,%di 94 dec %si 95 dec %di 96 rep movsb # Move BTX 97 cld # String ops inc 98/* 99 * Enable A20 so we can access memory above 1 meg. 100 * Use the zero-valued %cx as a timeout for embedded hardware which do not 101 * have a keyboard controller. 102 */ 103seta20: cli # Disable interrupts 104seta20.1: dec %cx # Timeout? 105 jz seta20.3 # Yes 106 inb $0x64,%al # Get status 107 testb $0x2,%al # Busy? 108 jnz seta20.1 # Yes 109 movb $0xd1,%al # Command: Write 110 outb %al,$0x64 # output port 111seta20.2: inb $0x64,%al # Get status 112 testb $0x2,%al # Busy? 113 jnz seta20.2 # Yes 114 movb $0xdf,%al # Enable 115 outb %al,$0x60 # A20 116seta20.3: sti # Enable interrupts 117 118/* 119 * Save drive number from BIOS so boot2 can see it and start BTX. 120 */ 121 movb %dl,MEM_ARG 122 jmp MEM_JMP # Start BTX 123end: 124