199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Copyright (c) 2001 John Baldwin <jhb@FreeBSD.org>
199767f8919635c4928607450d9e0abb932109ceToomas Soome# All rights reserved.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Redistribution and use in source and binary forms, with or without
199767f8919635c4928607450d9e0abb932109ceToomas Soome# modification, are permitted provided that the following conditions
199767f8919635c4928607450d9e0abb932109ceToomas Soome# are met:
199767f8919635c4928607450d9e0abb932109ceToomas Soome# 1. Redistributions of source code must retain the above copyright
199767f8919635c4928607450d9e0abb932109ceToomas Soome# notice, this list of conditions and the following disclaimer.
199767f8919635c4928607450d9e0abb932109ceToomas Soome# 2. Redistributions in binary form must reproduce the above copyright
199767f8919635c4928607450d9e0abb932109ceToomas Soome# notice, this list of conditions and the following disclaimer in the
199767f8919635c4928607450d9e0abb932109ceToomas Soome# documentation and/or other materials provided with the distribution.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
199767f8919635c4928607450d9e0abb932109ceToomas Soome# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
199767f8919635c4928607450d9e0abb932109ceToomas Soome# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
199767f8919635c4928607450d9e0abb932109ceToomas Soome# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
199767f8919635c4928607450d9e0abb932109ceToomas Soome# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
199767f8919635c4928607450d9e0abb932109ceToomas Soome# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
199767f8919635c4928607450d9e0abb932109ceToomas Soome# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
199767f8919635c4928607450d9e0abb932109ceToomas Soome# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
199767f8919635c4928607450d9e0abb932109ceToomas Soome# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
199767f8919635c4928607450d9e0abb932109ceToomas Soome# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
199767f8919635c4928607450d9e0abb932109ceToomas Soome# SUCH DAMAGE.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome# $FreeBSD$
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# This program is a freestanding boot program to load an a.out binary
199767f8919635c4928607450d9e0abb932109ceToomas Soome# from a CD-ROM booted with no emulation mode as described by the El
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Torito standard. Due to broken BIOSen that do not load the desired
199767f8919635c4928607450d9e0abb932109ceToomas Soome# number of sectors, we try to fit this in as small a space as possible.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Basically, we first create a set of boot arguments to pass to the loaded
199767f8919635c4928607450d9e0abb932109ceToomas Soome# binary. Then we attempt to load /boot/loader from the CD we were booted
199767f8919635c4928607450d9e0abb932109ceToomas Soome# off of.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include <bootargs.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Memory locations.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set MEM_PAGE_SIZE,0x1000 # memory page size, 4k
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set MEM_ARG,0x900 # Arguments at start
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set MEM_ARG_BTX,0xa100 # Where we move them to so the
199767f8919635c4928607450d9e0abb932109ceToomas Soome # BTX client can see them
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set MEM_ARG_SIZE,0x18 # Size of the arguments
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set MEM_BTX_ADDRESS,0x9000 # where BTX lives
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set MEM_BTX_ENTRY,0x9010 # where BTX starts to execute
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set MEM_BTX_OFFSET,MEM_PAGE_SIZE # offset of BTX in the loader
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set MEM_BTX_CLIENT,0xa000 # where BTX clients live
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# a.out header fields
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set AOUT_TEXT,0x04 # text segment size
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set AOUT_DATA,0x08 # data segment size
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set AOUT_BSS,0x0c # zero'd BSS size
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set AOUT_SYMBOLS,0x10 # symbol table
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set AOUT_ENTRY,0x14 # entry point
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set AOUT_HEADER,MEM_PAGE_SIZE # size of the a.out header
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Segment selectors.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set SEL_SDATA,0x8 # Supervisor data
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set SEL_RDATA,0x10 # Real mode data
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set SEL_SCODE,0x18 # PM-32 code
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set SEL_SCODE16,0x20 # PM-16 code
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# BTX constants
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set INT_SYS,0x30 # BTX syscall interrupt
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Constants for reading from the CD.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set ERROR_TIMEOUT,0x80 # BIOS timeout on read
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set NUM_RETRIES,3 # Num times to retry
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set SECTOR_SIZE,0x800 # size of a sector
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set SECTOR_SHIFT,11 # number of place to shift
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set BUFFER_LEN,0x100 # number of sectors in buffer
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set MAX_READ,0x10000 # max we can read at a time
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set MAX_READ_SEC,MAX_READ >> SECTOR_SHIFT
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set MEM_READ_BUFFER,0x9000 # buffer to read from CD
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set MEM_VOLDESC,MEM_READ_BUFFER # volume descriptor
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set MEM_DIR,MEM_VOLDESC+SECTOR_SIZE # Lookup buffer
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set VOLDESC_LBA,0x10 # LBA of vol descriptor
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set VD_PRIMARY,1 # Primary VD
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set VD_END,255 # VD Terminator
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set VD_ROOTDIR,156 # Offset of Root Dir Record
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set DIR_LEN,0 # Offset of Dir Record length
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set DIR_EA_LEN,1 # Offset of EA length
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set DIR_EXTENT,2 # Offset of 64-bit LBA
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set DIR_SIZE,10 # Offset of 64-bit length
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set DIR_NAMELEN,32 # Offset of 8-bit name len
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set DIR_NAME,33 # Offset of dir name
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# We expect to be loaded by the BIOS at 0x7c00 (standard boot loader entry
199767f8919635c4928607450d9e0abb932109ceToomas Soome# point)
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome .code16
199767f8919635c4928607450d9e0abb932109ceToomas Soome .globl start
199767f8919635c4928607450d9e0abb932109ceToomas Soome .org 0x0, 0x0
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Program start.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soomestart: jmp real_start
199767f8919635c4928607450d9e0abb932109ceToomas Soome .org 0x8, 0x8
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomebi_pvd: .long VOLDESC_LBA # LBA of primary volume desc
199767f8919635c4928607450d9e0abb932109ceToomas Soomebi_file: .long 0 # LBA of boot file.
199767f8919635c4928607450d9e0abb932109ceToomas Soomebi_length: .long 0 # Length of boot file.
199767f8919635c4928607450d9e0abb932109ceToomas Soomebi_csum: .long 0 # Checksum of boot file
199767f8919635c4928607450d9e0abb932109ceToomas Soomebi_reserved: .space (10*4) # Reserved
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomereal_start: cld # string ops inc
199767f8919635c4928607450d9e0abb932109ceToomas Soome xor %ax,%ax # zero %ax
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov %ax,%ss # setup the
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $start,%sp # stack
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov %ax,%ds # setup the
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov %ax,%es # data segments
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov %dl,drive # Save BIOS boot device
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $msg_welcome,%si # %ds:(%si) -> welcome message
199767f8919635c4928607450d9e0abb932109ceToomas Soome call putstr # display the welcome message
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Setup the arguments that the loader is expecting from boot[12]
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $msg_bootinfo,%si # %ds:(%si) -> boot args message
199767f8919635c4928607450d9e0abb932109ceToomas Soome call putstr # display the message
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $MEM_ARG,%bx # %ds:(%bx) -> boot args
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov %bx,%di # %es:(%di) -> boot args
199767f8919635c4928607450d9e0abb932109ceToomas Soome xor %eax,%eax # zero %eax
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $(MEM_ARG_SIZE/4),%cx # Size of arguments in 32-bit
199767f8919635c4928607450d9e0abb932109ceToomas Soome # dwords
199767f8919635c4928607450d9e0abb932109ceToomas Soome rep # Clear the arguments
199767f8919635c4928607450d9e0abb932109ceToomas Soome stosl # to zero
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov drive,%dl # Store BIOS boot device
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov %dl,0x4(%bx) # in kargs->bootdev
199767f8919635c4928607450d9e0abb932109ceToomas Soome or $KARGS_FLAGS_CD,0x8(%bx) # kargs->bootflags |=
199767f8919635c4928607450d9e0abb932109ceToomas Soome # KARGS_FLAGS_CD
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Load Volume Descriptor
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $VOLDESC_LBA,%eax # Set LBA of first VD
199767f8919635c4928607450d9e0abb932109ceToomas Soomeload_vd: push %eax # Save %eax
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $1,%dh # One sector
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $MEM_VOLDESC,%ebx # Destination
199767f8919635c4928607450d9e0abb932109ceToomas Soome call read # Read it in
199767f8919635c4928607450d9e0abb932109ceToomas Soome cmpb $VD_PRIMARY,(%bx) # Primary VD?
199767f8919635c4928607450d9e0abb932109ceToomas Soome je have_vd # Yes
199767f8919635c4928607450d9e0abb932109ceToomas Soome pop %eax # Prepare to
199767f8919635c4928607450d9e0abb932109ceToomas Soome inc %eax # try next
199767f8919635c4928607450d9e0abb932109ceToomas Soome cmpb $VD_END,(%bx) # Last VD?
199767f8919635c4928607450d9e0abb932109ceToomas Soome jne load_vd # No, read next
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $msg_novd,%si # No VD
199767f8919635c4928607450d9e0abb932109ceToomas Soome jmp error # Halt
199767f8919635c4928607450d9e0abb932109ceToomas Soomehave_vd: # Have Primary VD
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Try to look up the loader binary using the paths in the loader_paths
199767f8919635c4928607450d9e0abb932109ceToomas Soome# array.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $loader_paths,%si # Point to start of array
199767f8919635c4928607450d9e0abb932109ceToomas Soomelookup_path: push %si # Save file name pointer
199767f8919635c4928607450d9e0abb932109ceToomas Soome call lookup # Try to find file
199767f8919635c4928607450d9e0abb932109ceToomas Soome pop %di # Restore file name pointer
199767f8919635c4928607450d9e0abb932109ceToomas Soome jnc lookup_found # Found this file
199767f8919635c4928607450d9e0abb932109ceToomas Soome xor %al,%al # Look for next
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $0xffff,%cx # path name by
199767f8919635c4928607450d9e0abb932109ceToomas Soome repnz # scanning for
199767f8919635c4928607450d9e0abb932109ceToomas Soome scasb # nul char
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov %di,%si # Point %si at next path
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov (%si),%al # Get first char of next path
199767f8919635c4928607450d9e0abb932109ceToomas Soome or %al,%al # Is it double nul?
199767f8919635c4928607450d9e0abb932109ceToomas Soome jnz lookup_path # No, try it.
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $msg_failed,%si # Failed message
199767f8919635c4928607450d9e0abb932109ceToomas Soome jmp error # Halt
199767f8919635c4928607450d9e0abb932109ceToomas Soomelookup_found: # Found a loader file
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Load the binary into the buffer. Due to real mode addressing limitations
199767f8919635c4928607450d9e0abb932109ceToomas Soome# we have to read it in 64k chunks.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov DIR_SIZE(%bx),%eax # Read file length
199767f8919635c4928607450d9e0abb932109ceToomas Soome add $SECTOR_SIZE-1,%eax # Convert length to sectors
199767f8919635c4928607450d9e0abb932109ceToomas Soome shr $SECTOR_SHIFT,%eax
199767f8919635c4928607450d9e0abb932109ceToomas Soome cmp $BUFFER_LEN,%eax
199767f8919635c4928607450d9e0abb932109ceToomas Soome jbe load_sizeok
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $msg_load2big,%si # Error message
199767f8919635c4928607450d9e0abb932109ceToomas Soome call error
199767f8919635c4928607450d9e0abb932109ceToomas Soomeload_sizeok: movzbw %al,%cx # Num sectors to read
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov DIR_EXTENT(%bx),%eax # Load extent
199767f8919635c4928607450d9e0abb932109ceToomas Soome xor %edx,%edx
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov DIR_EA_LEN(%bx),%dl
199767f8919635c4928607450d9e0abb932109ceToomas Soome add %edx,%eax # Skip extended
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $MEM_READ_BUFFER,%ebx # Read into the buffer
199767f8919635c4928607450d9e0abb932109ceToomas Soomeload_loop: mov %cl,%dh
199767f8919635c4928607450d9e0abb932109ceToomas Soome cmp $MAX_READ_SEC,%cl # Truncate to max read size
199767f8919635c4928607450d9e0abb932109ceToomas Soome jbe load_notrunc
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $MAX_READ_SEC,%dh
199767f8919635c4928607450d9e0abb932109ceToomas Soomeload_notrunc: sub %dh,%cl # Update count
199767f8919635c4928607450d9e0abb932109ceToomas Soome push %eax # Save
199767f8919635c4928607450d9e0abb932109ceToomas Soome call read # Read it in
199767f8919635c4928607450d9e0abb932109ceToomas Soome pop %eax # Restore
199767f8919635c4928607450d9e0abb932109ceToomas Soome add $MAX_READ_SEC,%eax # Update LBA
199767f8919635c4928607450d9e0abb932109ceToomas Soome add $MAX_READ,%ebx # Update dest addr
199767f8919635c4928607450d9e0abb932109ceToomas Soome jcxz load_done # Done?
199767f8919635c4928607450d9e0abb932109ceToomas Soome jmp load_loop # Keep going
199767f8919635c4928607450d9e0abb932109ceToomas Soomeload_done:
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Turn on the A20 address line
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome call seta20 # Turn A20 on
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Relocate the loader and BTX using a very lazy protected mode
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $msg_relocate,%si # Display the
199767f8919635c4928607450d9e0abb932109ceToomas Soome call putstr # relocation message
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov MEM_READ_BUFFER+AOUT_ENTRY,%edi # %edi is the destination
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $(MEM_READ_BUFFER+AOUT_HEADER),%esi # %esi is
199767f8919635c4928607450d9e0abb932109ceToomas Soome # the start of the text
199767f8919635c4928607450d9e0abb932109ceToomas Soome # segment
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov MEM_READ_BUFFER+AOUT_TEXT,%ecx # %ecx = length of the text
199767f8919635c4928607450d9e0abb932109ceToomas Soome # segment
199767f8919635c4928607450d9e0abb932109ceToomas Soome push %edi # Save entry point for later
199767f8919635c4928607450d9e0abb932109ceToomas Soome lgdt gdtdesc # setup our own gdt
199767f8919635c4928607450d9e0abb932109ceToomas Soome cli # turn off interrupts
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov %cr0,%eax # Turn on
199767f8919635c4928607450d9e0abb932109ceToomas Soome or $0x1,%al # protected
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov %eax,%cr0 # mode
199767f8919635c4928607450d9e0abb932109ceToomas Soome ljmp $SEL_SCODE,$pm_start # long jump to clear the
199767f8919635c4928607450d9e0abb932109ceToomas Soome # instruction pre-fetch queue
199767f8919635c4928607450d9e0abb932109ceToomas Soome .code32
199767f8919635c4928607450d9e0abb932109ceToomas Soomepm_start: mov $SEL_SDATA,%ax # Initialize
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov %ax,%ds # %ds and
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov %ax,%es # %es to a flat selector
199767f8919635c4928607450d9e0abb932109ceToomas Soome rep # Relocate the
199767f8919635c4928607450d9e0abb932109ceToomas Soome movsb # text segment
199767f8919635c4928607450d9e0abb932109ceToomas Soome add $(MEM_PAGE_SIZE - 1),%edi # pad %edi out to a new page
199767f8919635c4928607450d9e0abb932109ceToomas Soome and $~(MEM_PAGE_SIZE - 1),%edi # for the data segment
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov MEM_READ_BUFFER+AOUT_DATA,%ecx # size of the data segment
199767f8919635c4928607450d9e0abb932109ceToomas Soome rep # Relocate the
199767f8919635c4928607450d9e0abb932109ceToomas Soome movsb # data segment
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov MEM_READ_BUFFER+AOUT_BSS,%ecx # size of the bss
199767f8919635c4928607450d9e0abb932109ceToomas Soome xor %eax,%eax # zero %eax
199767f8919635c4928607450d9e0abb932109ceToomas Soome add $3,%cl # round %ecx up to
199767f8919635c4928607450d9e0abb932109ceToomas Soome shr $2,%ecx # a multiple of 4
199767f8919635c4928607450d9e0abb932109ceToomas Soome rep # zero the
199767f8919635c4928607450d9e0abb932109ceToomas Soome stosl # bss
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov MEM_READ_BUFFER+AOUT_ENTRY,%esi # %esi -> relocated loader
199767f8919635c4928607450d9e0abb932109ceToomas Soome add $MEM_BTX_OFFSET,%esi # %esi -> BTX in the loader
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $MEM_BTX_ADDRESS,%edi # %edi -> where BTX needs to go
199767f8919635c4928607450d9e0abb932109ceToomas Soome movzwl 0xa(%esi),%ecx # %ecx -> length of BTX
199767f8919635c4928607450d9e0abb932109ceToomas Soome rep # Relocate
199767f8919635c4928607450d9e0abb932109ceToomas Soome movsb # BTX
199767f8919635c4928607450d9e0abb932109ceToomas Soome ljmp $SEL_SCODE16,$pm_16 # Jump to 16-bit PM
199767f8919635c4928607450d9e0abb932109ceToomas Soome .code16
199767f8919635c4928607450d9e0abb932109ceToomas Soomepm_16: mov $SEL_RDATA,%ax # Initialize
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov %ax,%ds # %ds and
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov %ax,%es # %es to a real mode selector
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov %cr0,%eax # Turn off
199767f8919635c4928607450d9e0abb932109ceToomas Soome and $~0x1,%al # protected
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov %eax,%cr0 # mode
199767f8919635c4928607450d9e0abb932109ceToomas Soome ljmp $0,$pm_end # Long jump to clear the
199767f8919635c4928607450d9e0abb932109ceToomas Soome # instruction pre-fetch queue
199767f8919635c4928607450d9e0abb932109ceToomas Soomepm_end: sti # Turn interrupts back on now
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Copy the BTX client to MEM_BTX_CLIENT
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome xor %ax,%ax # zero %ax and set
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov %ax,%ds # %ds and %es
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov %ax,%es # to segment 0
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $MEM_BTX_CLIENT,%di # Prepare to relocate
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $btx_client,%si # the simple btx client
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $(btx_client_end-btx_client),%cx # length of btx client
199767f8919635c4928607450d9e0abb932109ceToomas Soome rep # Relocate the
199767f8919635c4928607450d9e0abb932109ceToomas Soome movsb # simple BTX client
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Copy the boot[12] args to where the BTX client can see them
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $MEM_ARG,%si # where the args are at now
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $MEM_ARG_BTX,%di # where the args are moving to
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $(MEM_ARG_SIZE/4),%cx # size of the arguments in longs
199767f8919635c4928607450d9e0abb932109ceToomas Soome rep # Relocate
199767f8919635c4928607450d9e0abb932109ceToomas Soome movsl # the words
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Save the entry point so the client can get to it later on
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome pop %eax # Restore saved entry point
199767f8919635c4928607450d9e0abb932109ceToomas Soome stosl # and add it to the end of
199767f8919635c4928607450d9e0abb932109ceToomas Soome # the arguments
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Now we just start up BTX and let it do the rest
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $msg_jump,%si # Display the
199767f8919635c4928607450d9e0abb932109ceToomas Soome call putstr # jump message
199767f8919635c4928607450d9e0abb932109ceToomas Soome ljmp $0,$MEM_BTX_ENTRY # Jump to the BTX entry point
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Lookup the file in the path at [SI] from the root directory.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Trashes: All but BX
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Returns: CF = 0 (success), BX = pointer to record
199767f8919635c4928607450d9e0abb932109ceToomas Soome# CF = 1 (not found)
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soomelookup: mov $VD_ROOTDIR+MEM_VOLDESC,%bx # Root directory record
199767f8919635c4928607450d9e0abb932109ceToomas Soome push %si
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $msg_lookup,%si # Display lookup message
199767f8919635c4928607450d9e0abb932109ceToomas Soome call putstr
199767f8919635c4928607450d9e0abb932109ceToomas Soome pop %si
199767f8919635c4928607450d9e0abb932109ceToomas Soome push %si
199767f8919635c4928607450d9e0abb932109ceToomas Soome call putstr
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $msg_lookup2,%si
199767f8919635c4928607450d9e0abb932109ceToomas Soome call putstr
199767f8919635c4928607450d9e0abb932109ceToomas Soome pop %si
199767f8919635c4928607450d9e0abb932109ceToomas Soomelookup_dir: lodsb # Get first char of path
199767f8919635c4928607450d9e0abb932109ceToomas Soome cmp $0,%al # Are we done?
199767f8919635c4928607450d9e0abb932109ceToomas Soome je lookup_done # Yes
199767f8919635c4928607450d9e0abb932109ceToomas Soome cmp $'/',%al # Skip path separator.
199767f8919635c4928607450d9e0abb932109ceToomas Soome je lookup_dir
199767f8919635c4928607450d9e0abb932109ceToomas Soome dec %si # Undo lodsb side effect
199767f8919635c4928607450d9e0abb932109ceToomas Soome call find_file # Lookup first path item
199767f8919635c4928607450d9e0abb932109ceToomas Soome jnc lookup_dir # Try next component
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $msg_lookupfail,%si # Not found message
199767f8919635c4928607450d9e0abb932109ceToomas Soome call putstr
199767f8919635c4928607450d9e0abb932109ceToomas Soome stc # Set carry
199767f8919635c4928607450d9e0abb932109ceToomas Soome ret
199767f8919635c4928607450d9e0abb932109ceToomas Soome jmp error
199767f8919635c4928607450d9e0abb932109ceToomas Soomelookup_done: mov $msg_lookupok,%si # Success message
199767f8919635c4928607450d9e0abb932109ceToomas Soome call putstr
199767f8919635c4928607450d9e0abb932109ceToomas Soome clc # Clear carry
199767f8919635c4928607450d9e0abb932109ceToomas Soome ret
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Lookup file at [SI] in directory whose record is at [BX].
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Trashes: All but returns
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Returns: CF = 0 (success), BX = pointer to record, SI = next path item
199767f8919635c4928607450d9e0abb932109ceToomas Soome# CF = 1 (not found), SI = preserved
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soomefind_file: mov DIR_EXTENT(%bx),%eax # Load extent
199767f8919635c4928607450d9e0abb932109ceToomas Soome xor %edx,%edx
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov DIR_EA_LEN(%bx),%dl
199767f8919635c4928607450d9e0abb932109ceToomas Soome add %edx,%eax # Skip extended attributes
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov %eax,rec_lba # Save LBA
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov DIR_SIZE(%bx),%eax # Save size
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov %eax,rec_size
199767f8919635c4928607450d9e0abb932109ceToomas Soome xor %cl,%cl # Zero length
199767f8919635c4928607450d9e0abb932109ceToomas Soome push %si # Save
199767f8919635c4928607450d9e0abb932109ceToomas Soomeff.namelen: inc %cl # Update length
199767f8919635c4928607450d9e0abb932109ceToomas Soome lodsb # Read char
199767f8919635c4928607450d9e0abb932109ceToomas Soome cmp $0,%al # Nul?
199767f8919635c4928607450d9e0abb932109ceToomas Soome je ff.namedone # Yes
199767f8919635c4928607450d9e0abb932109ceToomas Soome cmp $'/',%al # Path separator?
199767f8919635c4928607450d9e0abb932109ceToomas Soome jnz ff.namelen # No, keep going
199767f8919635c4928607450d9e0abb932109ceToomas Soomeff.namedone: dec %cl # Adjust length and save
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov %cl,name_len
199767f8919635c4928607450d9e0abb932109ceToomas Soome pop %si # Restore
199767f8919635c4928607450d9e0abb932109ceToomas Soomeff.load: mov rec_lba,%eax # Load LBA
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $MEM_DIR,%ebx # Address buffer
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $1,%dh # One sector
199767f8919635c4928607450d9e0abb932109ceToomas Soome call read # Read directory block
199767f8919635c4928607450d9e0abb932109ceToomas Soome incl rec_lba # Update LBA to next block
199767f8919635c4928607450d9e0abb932109ceToomas Soomeff.scan: mov %ebx,%edx # Check for EOF
199767f8919635c4928607450d9e0abb932109ceToomas Soome sub $MEM_DIR,%edx
199767f8919635c4928607450d9e0abb932109ceToomas Soome cmp %edx,rec_size
199767f8919635c4928607450d9e0abb932109ceToomas Soome ja ff.scan.1
199767f8919635c4928607450d9e0abb932109ceToomas Soome stc # EOF reached
199767f8919635c4928607450d9e0abb932109ceToomas Soome ret
199767f8919635c4928607450d9e0abb932109ceToomas Soomeff.scan.1: cmpb $0,DIR_LEN(%bx) # Last record in block?
199767f8919635c4928607450d9e0abb932109ceToomas Soome je ff.nextblock
199767f8919635c4928607450d9e0abb932109ceToomas Soome push %si # Save
199767f8919635c4928607450d9e0abb932109ceToomas Soome movzbw DIR_NAMELEN(%bx),%si # Find end of string
199767f8919635c4928607450d9e0abb932109ceToomas Soomeff.checkver: cmpb $'0',DIR_NAME-1(%bx,%si) # Less than '0'?
199767f8919635c4928607450d9e0abb932109ceToomas Soome jb ff.checkver.1
199767f8919635c4928607450d9e0abb932109ceToomas Soome cmpb $'9',DIR_NAME-1(%bx,%si) # Greater than '9'?
199767f8919635c4928607450d9e0abb932109ceToomas Soome ja ff.checkver.1
199767f8919635c4928607450d9e0abb932109ceToomas Soome dec %si # Next char
199767f8919635c4928607450d9e0abb932109ceToomas Soome jnz ff.checkver
199767f8919635c4928607450d9e0abb932109ceToomas Soome jmp ff.checklen # All numbers in name, so
199767f8919635c4928607450d9e0abb932109ceToomas Soome # no version
199767f8919635c4928607450d9e0abb932109ceToomas Soomeff.checkver.1: movzbw DIR_NAMELEN(%bx),%cx
199767f8919635c4928607450d9e0abb932109ceToomas Soome cmp %cx,%si # Did we find any digits?
199767f8919635c4928607450d9e0abb932109ceToomas Soome je ff.checkdot # No
199767f8919635c4928607450d9e0abb932109ceToomas Soome cmpb $';',DIR_NAME-1(%bx,%si) # Check for semicolon
199767f8919635c4928607450d9e0abb932109ceToomas Soome jne ff.checkver.2
199767f8919635c4928607450d9e0abb932109ceToomas Soome dec %si # Skip semicolon
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov %si,%cx
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov %cl,DIR_NAMELEN(%bx) # Adjust length
199767f8919635c4928607450d9e0abb932109ceToomas Soome jmp ff.checkdot
199767f8919635c4928607450d9e0abb932109ceToomas Soomeff.checkver.2: mov %cx,%si # Restore %si to end of string
199767f8919635c4928607450d9e0abb932109ceToomas Soomeff.checkdot: cmpb $'.',DIR_NAME-1(%bx,%si) # Trailing dot?
199767f8919635c4928607450d9e0abb932109ceToomas Soome jne ff.checklen # No
199767f8919635c4928607450d9e0abb932109ceToomas Soome decb DIR_NAMELEN(%bx) # Adjust length
199767f8919635c4928607450d9e0abb932109ceToomas Soomeff.checklen: pop %si # Restore
199767f8919635c4928607450d9e0abb932109ceToomas Soome movzbw name_len,%cx # Load length of name
199767f8919635c4928607450d9e0abb932109ceToomas Soome cmp %cl,DIR_NAMELEN(%bx) # Does length match?
199767f8919635c4928607450d9e0abb932109ceToomas Soome je ff.checkname # Yes, check name
199767f8919635c4928607450d9e0abb932109ceToomas Soomeff.nextrec: add DIR_LEN(%bx),%bl # Next record
199767f8919635c4928607450d9e0abb932109ceToomas Soome adc $0,%bh
199767f8919635c4928607450d9e0abb932109ceToomas Soome jmp ff.scan
199767f8919635c4928607450d9e0abb932109ceToomas Soomeff.nextblock: subl $SECTOR_SIZE,rec_size # Adjust size
199767f8919635c4928607450d9e0abb932109ceToomas Soome jnc ff.load # If subtract ok, keep going
199767f8919635c4928607450d9e0abb932109ceToomas Soome ret # End of file, so not found
199767f8919635c4928607450d9e0abb932109ceToomas Soomeff.checkname: lea DIR_NAME(%bx),%di # Address name in record
199767f8919635c4928607450d9e0abb932109ceToomas Soome push %si # Save
199767f8919635c4928607450d9e0abb932109ceToomas Soome repe cmpsb # Compare name
199767f8919635c4928607450d9e0abb932109ceToomas Soome je ff.match # We have a winner!
199767f8919635c4928607450d9e0abb932109ceToomas Soome pop %si # Restore
199767f8919635c4928607450d9e0abb932109ceToomas Soome jmp ff.nextrec # Keep looking.
199767f8919635c4928607450d9e0abb932109ceToomas Soomeff.match: add $2,%sp # Discard saved %si
199767f8919635c4928607450d9e0abb932109ceToomas Soome clc # Clear carry
199767f8919635c4928607450d9e0abb932109ceToomas Soome ret
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Load DH sectors starting at LBA EAX into [EBX].
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Trashes: EAX
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soomeread: push %si # Save
199767f8919635c4928607450d9e0abb932109ceToomas Soome push %cx # Save since some BIOSs trash
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov %eax,edd_lba # LBA to read from
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov %ebx,%eax # Convert address
199767f8919635c4928607450d9e0abb932109ceToomas Soome shr $4,%eax # to segment
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov %ax,edd_addr+0x2 # and store
199767f8919635c4928607450d9e0abb932109ceToomas Soomeread.retry: call twiddle # Entertain the user
199767f8919635c4928607450d9e0abb932109ceToomas Soome push %dx # Save
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $edd_packet,%si # Address Packet
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov %dh,edd_len # Set length
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov drive,%dl # BIOS Device
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $0x42,%ah # BIOS: Extended Read
199767f8919635c4928607450d9e0abb932109ceToomas Soome int $0x13 # Call BIOS
199767f8919635c4928607450d9e0abb932109ceToomas Soome pop %dx # Restore
199767f8919635c4928607450d9e0abb932109ceToomas Soome jc read.fail # Worked?
199767f8919635c4928607450d9e0abb932109ceToomas Soome pop %cx # Restore
199767f8919635c4928607450d9e0abb932109ceToomas Soome pop %si
199767f8919635c4928607450d9e0abb932109ceToomas Soome ret # Return
199767f8919635c4928607450d9e0abb932109ceToomas Soomeread.fail: cmp $ERROR_TIMEOUT,%ah # Timeout?
199767f8919635c4928607450d9e0abb932109ceToomas Soome je read.retry # Yes, Retry.
199767f8919635c4928607450d9e0abb932109ceToomas Soomeread.error: mov %ah,%al # Save error
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $hex_error,%di # Format it
199767f8919635c4928607450d9e0abb932109ceToomas Soome call hex8 # as hex
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $msg_badread,%si # Display Read error message
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Display error message at [SI] and halt.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soomeerror: call putstr # Display message
199767f8919635c4928607450d9e0abb932109ceToomas Soomehalt: hlt
199767f8919635c4928607450d9e0abb932109ceToomas Soome jmp halt # Spin
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Display a null-terminated string.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Trashes: AX, SI
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soomeputstr: push %bx # Save
199767f8919635c4928607450d9e0abb932109ceToomas Soomeputstr.load: lodsb # load %al from %ds:(%si)
199767f8919635c4928607450d9e0abb932109ceToomas Soome test %al,%al # stop at null
199767f8919635c4928607450d9e0abb932109ceToomas Soome jnz putstr.putc # if the char != null, output it
199767f8919635c4928607450d9e0abb932109ceToomas Soome pop %bx # Restore
199767f8919635c4928607450d9e0abb932109ceToomas Soome ret # return when null is hit
199767f8919635c4928607450d9e0abb932109ceToomas Soomeputstr.putc: call putc # output char
199767f8919635c4928607450d9e0abb932109ceToomas Soome jmp putstr.load # next char
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Display a single char.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soomeputc: mov $0x7,%bx # attribute for output
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $0xe,%ah # BIOS: put_char
199767f8919635c4928607450d9e0abb932109ceToomas Soome int $0x10 # call BIOS, print char in %al
199767f8919635c4928607450d9e0abb932109ceToomas Soome ret # Return to caller
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Output the "twiddle"
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soometwiddle: push %ax # Save
199767f8919635c4928607450d9e0abb932109ceToomas Soome push %bx # Save
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov twiddle_index,%al # Load index
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $twiddle_chars,%bx # Address table
199767f8919635c4928607450d9e0abb932109ceToomas Soome inc %al # Next
199767f8919635c4928607450d9e0abb932109ceToomas Soome and $3,%al # char
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov %al,twiddle_index # Save index for next call
199767f8919635c4928607450d9e0abb932109ceToomas Soome xlat # Get char
199767f8919635c4928607450d9e0abb932109ceToomas Soome call putc # Output it
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $8,%al # Backspace
199767f8919635c4928607450d9e0abb932109ceToomas Soome call putc # Output it
199767f8919635c4928607450d9e0abb932109ceToomas Soome pop %bx # Restore
199767f8919635c4928607450d9e0abb932109ceToomas Soome pop %ax # Restore
199767f8919635c4928607450d9e0abb932109ceToomas Soome ret
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Enable A20. Put an upper limit on the amount of time we wait for the
199767f8919635c4928607450d9e0abb932109ceToomas Soome# keyboard controller to get ready (65K x ISA access time). If
199767f8919635c4928607450d9e0abb932109ceToomas Soome# we wait more than that amount, the hardware is probably
199767f8919635c4928607450d9e0abb932109ceToomas Soome# legacy-free and simply doesn't have a keyboard controller.
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Thus, the A20 line is already enabled.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soomeseta20: cli # Disable interrupts
199767f8919635c4928607450d9e0abb932109ceToomas Soome xor %cx,%cx # Clear
199767f8919635c4928607450d9e0abb932109ceToomas Soomeseta20.1: inc %cx # Increment, overflow?
199767f8919635c4928607450d9e0abb932109ceToomas Soome jz seta20.3 # Yes
199767f8919635c4928607450d9e0abb932109ceToomas Soome in $0x64,%al # Get status
199767f8919635c4928607450d9e0abb932109ceToomas Soome test $0x2,%al # Busy?
199767f8919635c4928607450d9e0abb932109ceToomas Soome jnz seta20.1 # Yes
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $0xd1,%al # Command: Write
199767f8919635c4928607450d9e0abb932109ceToomas Soome out %al,$0x64 # output port
199767f8919635c4928607450d9e0abb932109ceToomas Soomeseta20.2: in $0x64,%al # Get status
199767f8919635c4928607450d9e0abb932109ceToomas Soome test $0x2,%al # Busy?
199767f8919635c4928607450d9e0abb932109ceToomas Soome jnz seta20.2 # Yes
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $0xdf,%al # Enable
199767f8919635c4928607450d9e0abb932109ceToomas Soome out %al,$0x60 # A20
199767f8919635c4928607450d9e0abb932109ceToomas Soomeseta20.3: sti # Enable interrupts
199767f8919635c4928607450d9e0abb932109ceToomas Soome ret # To caller
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Convert AL to hex, saving the result to [EDI].
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soomehex8: pushl %eax # Save
199767f8919635c4928607450d9e0abb932109ceToomas Soome shrb $0x4,%al # Do upper
199767f8919635c4928607450d9e0abb932109ceToomas Soome call hex8.1 # 4
199767f8919635c4928607450d9e0abb932109ceToomas Soome popl %eax # Restore
199767f8919635c4928607450d9e0abb932109ceToomas Soomehex8.1: andb $0xf,%al # Get lower 4
199767f8919635c4928607450d9e0abb932109ceToomas Soome cmpb $0xa,%al # Convert
199767f8919635c4928607450d9e0abb932109ceToomas Soome sbbb $0x69,%al # to hex
199767f8919635c4928607450d9e0abb932109ceToomas Soome das # digit
199767f8919635c4928607450d9e0abb932109ceToomas Soome orb $0x20,%al # To lower case
199767f8919635c4928607450d9e0abb932109ceToomas Soome stosb # Save char
199767f8919635c4928607450d9e0abb932109ceToomas Soome ret # (Recursive)
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# BTX client to start btxldr
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome .code32
199767f8919635c4928607450d9e0abb932109ceToomas Soomebtx_client: mov $(MEM_ARG_BTX-MEM_BTX_CLIENT+MEM_ARG_SIZE-4), %esi
199767f8919635c4928607450d9e0abb932109ceToomas Soome # %ds:(%esi) -> end
199767f8919635c4928607450d9e0abb932109ceToomas Soome # of boot[12] args
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $(MEM_ARG_SIZE/4),%ecx # Number of words to push
199767f8919635c4928607450d9e0abb932109ceToomas Soome std # Go backwards
199767f8919635c4928607450d9e0abb932109ceToomas Soomepush_arg: lodsl # Read argument
199767f8919635c4928607450d9e0abb932109ceToomas Soome push %eax # Push it onto the stack
199767f8919635c4928607450d9e0abb932109ceToomas Soome loop push_arg # Push all of the arguments
199767f8919635c4928607450d9e0abb932109ceToomas Soome cld # In case anyone depends on this
199767f8919635c4928607450d9e0abb932109ceToomas Soome pushl MEM_ARG_BTX-MEM_BTX_CLIENT+MEM_ARG_SIZE # Entry point of
199767f8919635c4928607450d9e0abb932109ceToomas Soome # the loader
199767f8919635c4928607450d9e0abb932109ceToomas Soome push %eax # Emulate a near call
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov $0x1,%eax # 'exec' system call
199767f8919635c4928607450d9e0abb932109ceToomas Soome int $INT_SYS # BTX system call
199767f8919635c4928607450d9e0abb932109ceToomas Soomebtx_client_end:
199767f8919635c4928607450d9e0abb932109ceToomas Soome .code16
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome .p2align 4
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Global descriptor table.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soomegdt: .word 0x0,0x0,0x0,0x0 # Null entry
199767f8919635c4928607450d9e0abb932109ceToomas Soome .word 0xffff,0x0,0x9200,0xcf # SEL_SDATA
199767f8919635c4928607450d9e0abb932109ceToomas Soome .word 0xffff,0x0,0x9200,0x0 # SEL_RDATA
199767f8919635c4928607450d9e0abb932109ceToomas Soome .word 0xffff,0x0,0x9a00,0xcf # SEL_SCODE (32-bit)
199767f8919635c4928607450d9e0abb932109ceToomas Soome .word 0xffff,0x0,0x9a00,0x8f # SEL_SCODE16 (16-bit)
199767f8919635c4928607450d9e0abb932109ceToomas Soomegdt.1:
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Pseudo-descriptors.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soomegdtdesc: .word gdt.1-gdt-1 # Limit
199767f8919635c4928607450d9e0abb932109ceToomas Soome .long gdt # Base
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# EDD Packet
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soomeedd_packet: .byte 0x10 # Length
199767f8919635c4928607450d9e0abb932109ceToomas Soome .byte 0 # Reserved
199767f8919635c4928607450d9e0abb932109ceToomas Soomeedd_len: .byte 0x0 # Num to read
199767f8919635c4928607450d9e0abb932109ceToomas Soome .byte 0 # Reserved
199767f8919635c4928607450d9e0abb932109ceToomas Soomeedd_addr: .word 0x0,0x0 # Seg:Off
199767f8919635c4928607450d9e0abb932109ceToomas Soomeedd_lba: .quad 0x0 # LBA
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomedrive: .byte 0
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# State for searching dir
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soomerec_lba: .long 0x0 # LBA (adjusted for EA)
199767f8919635c4928607450d9e0abb932109ceToomas Soomerec_size: .long 0x0 # File size
199767f8919635c4928607450d9e0abb932109ceToomas Soomename_len: .byte 0x0 # Length of current name
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soometwiddle_index: .byte 0x0
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomemsg_welcome: .asciz "CD Loader 1.2\r\n\n"
199767f8919635c4928607450d9e0abb932109ceToomas Soomemsg_bootinfo: .asciz "Building the boot loader arguments\r\n"
199767f8919635c4928607450d9e0abb932109ceToomas Soomemsg_relocate: .asciz "Relocating the loader and the BTX\r\n"
199767f8919635c4928607450d9e0abb932109ceToomas Soomemsg_jump: .asciz "Starting the BTX loader\r\n"
199767f8919635c4928607450d9e0abb932109ceToomas Soomemsg_badread: .ascii "Read Error: 0x"
199767f8919635c4928607450d9e0abb932109ceToomas Soomehex_error: .asciz "00\r\n"
199767f8919635c4928607450d9e0abb932109ceToomas Soomemsg_novd: .asciz "Could not find Primary Volume Descriptor\r\n"
199767f8919635c4928607450d9e0abb932109ceToomas Soomemsg_lookup: .asciz "Looking up "
199767f8919635c4928607450d9e0abb932109ceToomas Soomemsg_lookup2: .asciz "... "
199767f8919635c4928607450d9e0abb932109ceToomas Soomemsg_lookupok: .asciz "Found\r\n"
199767f8919635c4928607450d9e0abb932109ceToomas Soomemsg_lookupfail: .asciz "File not found\r\n"
199767f8919635c4928607450d9e0abb932109ceToomas Soomemsg_load2big: .asciz "File too big\r\n"
199767f8919635c4928607450d9e0abb932109ceToomas Soomemsg_failed: .asciz "Boot failed\r\n"
199767f8919635c4928607450d9e0abb932109ceToomas Soometwiddle_chars: .ascii "|/-\\"
199767f8919635c4928607450d9e0abb932109ceToomas Soomeloader_paths: .asciz "/BOOT/ZFSLOADER"
199767f8919635c4928607450d9e0abb932109ceToomas Soome .asciz "/boot/zfsloader"
199767f8919635c4928607450d9e0abb932109ceToomas Soome .byte 0