/*-1* Copyright (c) 2007 Yahoo!, Inc.2* All rights reserved.3* Written by: John Baldwin <[email protected]>4*5* Redistribution and use in source and binary forms, with or without6* modification, are permitted provided that the following conditions7* are met:8* 1. Redistributions of source code must retain the above copyright9* notice, this list of conditions and the following disclaimer.10* 2. Redistributions in binary form must reproduce the above copyright11* notice, this list of conditions and the following disclaimer in the12* documentation and/or other materials provided with the distribution.13* 3. Neither the name of the author nor the names of any co-contributors14* may be used to endorse or promote products derived from this software15* without specific prior written permission.16*17* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND18* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE19* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE20* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE21* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL22* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS23* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)24* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT25* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY26* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF27* SUCH DAMAGE.28*29* Partly from: src/sys/boot/i386/boot2/boot1.S 1.3130*/3132/* Memory Locations */33.set MEM_REL,0x700 # Relocation address34.set MEM_ARG,0x900 # Arguments35.set MEM_ORG,0x7c00 # Origin36.set MEM_BUF,0x8cec # Load area37.set MEM_BTX,0x9000 # BTX start38.set MEM_JMP,0x9010 # BTX entry point39.set MEM_USR,0xa000 # Client start40.set BDA_BOOT,0x472 # Boot howto flag4142/* Misc. Constants */43.set SIZ_PAG,0x1000 # Page size44.set SIZ_SEC,0x200 # Sector size45.set COPY_BLKS,0x8 # Number of blocks46# to copy for boot2 (<= 15)47.set COPY_BLK_SZ,0x8000 # Copy in 32k blocks; must be48# a multiple of 16 bytes4950.globl start51.code165253/*54* Copy BTX and boot2 to the right locations and start it all up.55*/5657/*58* Setup the segment registers to flat addressing (segment 0) and setup the59* stack to end just below the start of our code.60*/61start: xor %cx,%cx # Zero62mov %cx,%es # Address63mov %cx,%ds # data64mov %cx,%ss # Set up65mov $start,%sp # stack6667/*68* BTX is right after us at 'end'. We read the length of BTX out of69* its header to find boot2. We need to copy boot2 to MEM_USR and BTX70* to MEM_BTX. Since those might overlap, we have to copy boot271* backwards first and then copy BTX. We aren't sure exactly how long72* boot2 is, but it's currently under 256kB so we'll copy 8 blocks of 32kB73* each; this can be adjusted via COPY_BLK and COPY_BLK_SZ above.74*/75mov $end,%bx # BTX76mov 0xa(%bx),%si # Get BTX length and set77add %bx,%si # %si to start of boot278dec %si # Set %ds:%si to point at the79mov %si,%ax # last byte we want to copy80shr $4,%ax # from boot2, with %si made as81add $(COPY_BLKS*COPY_BLK_SZ/16),%ax # small as possible.82and $0xf,%si #83mov %ax,%ds #84mov $MEM_USR/16,%ax # Set %es:(-1) to point at85add $(COPY_BLKS*COPY_BLK_SZ/16),%ax # the last byte we86mov %ax,%es # want to copy boot2 into.87mov $COPY_BLKS,%bx # Copy COPY_BLKS 32k blocks88copyloop:89add $COPY_BLK_SZ,%si # Adjust %ds:%si to point at90mov %ds,%ax # the end of the next 32k to91sub $COPY_BLK_SZ/16,%ax # copy from boot292mov %ax,%ds93mov $COPY_BLK_SZ-1,%di # Adjust %es:%di to point at94mov %es,%ax # the end of the next 32k into95sub $COPY_BLK_SZ/16,%ax # which we want boot2 copied96mov %ax,%es97mov $COPY_BLK_SZ,%cx # Copy 32k98std99rep movsb100dec %bx101jnz copyloop102mov %cx,%ds # Reset %ds and %es103mov %cx,%es104mov $end,%bx # BTX105mov 0xa(%bx),%cx # Get BTX length and set106mov %bx,%si # %si to end of BTX107mov $MEM_BTX,%di # %di -> end of BTX at108add %cx,%si # MEM_BTX109add %cx,%di110dec %si111dec %di112rep movsb # Move BTX113cld # String ops inc114/*115* Enable A20 so we can access memory above 1 meg.116* Use the zero-valued %cx as a timeout for embedded hardware which do not117* have a keyboard controller.118*/119seta20: cli # Disable interrupts120seta20.1: dec %cx # Timeout?121jz seta20.3 # Yes122inb $0x64,%al # Get status123testb $0x2,%al # Busy?124jnz seta20.1 # Yes125movb $0xd1,%al # Command: Write126outb %al,$0x64 # output port127seta20.2: inb $0x64,%al # Get status128testb $0x2,%al # Busy?129jnz seta20.2 # Yes130movb $0xdf,%al # Enable131outb %al,$0x60 # A20132seta20.3: sti # Enable interrupts133134/*135* Save drive number from BIOS so boot2 can see it and start BTX.136*/137movb %dl,MEM_ARG138jmp start+MEM_JMP-MEM_ORG # Start BTX139end:140141142