summaryrefslogtreecommitdiffstats
path: root/sys/boot/i386/btx
diff options
context:
space:
mode:
authorrnordier <rnordier@FreeBSD.org>1998-09-12 06:30:26 +0000
committerrnordier <rnordier@FreeBSD.org>1998-09-12 06:30:26 +0000
commitb9a6cd338323b96f93783141570f6cb19aeb4fdd (patch)
treeee2c8bd6677da4e6cd627f5df6a82714783d3d75 /sys/boot/i386/btx
parent10a70998a1fa524cef24deec50388539a3502d05 (diff)
downloadFreeBSD-src-b9a6cd338323b96f93783141570f6cb19aeb4fdd.zip
FreeBSD-src-b9a6cd338323b96f93783141570f6cb19aeb4fdd.tar.gz
Add btxldr, a BTX loader for ELF clients.
Diffstat (limited to 'sys/boot/i386/btx')
-rw-r--r--sys/boot/i386/btx/Makefile4
-rw-r--r--sys/boot/i386/btx/btxldr/Makefile20
-rw-r--r--sys/boot/i386/btx/btxldr/btxldr.S368
-rw-r--r--sys/boot/i386/btx/btxldr/btxldr.s368
4 files changed, 758 insertions, 2 deletions
diff --git a/sys/boot/i386/btx/Makefile b/sys/boot/i386/btx/Makefile
index 92404c6..3e2ea39 100644
--- a/sys/boot/i386/btx/Makefile
+++ b/sys/boot/i386/btx/Makefile
@@ -1,5 +1,5 @@
-# $Id:$
+# $Id: Makefile,v 1.1.1.1 1998/09/12 04:29:22 rnordier Exp $
-SUBDIR= btx
+SUBDIR= btx btxldr
.include <bsd.subdir.mk>
diff --git a/sys/boot/i386/btx/btxldr/Makefile b/sys/boot/i386/btx/btxldr/Makefile
new file mode 100644
index 0000000..97c8e7f
--- /dev/null
+++ b/sys/boot/i386/btx/btxldr/Makefile
@@ -0,0 +1,20 @@
+# $Id:$
+
+ORG=0x100000
+
+all: btxldr
+
+btxldr: btxldr.o
+.if ${OBJFORMAT} == aout
+ ${LD} -nostdlib -N -s -T ${ORG} -o btxldr.out btxldr.o
+ dd if=btxldr.out of=${.TARGET} ibs=32 skip=1
+.else
+ ${LD} -N -e start -Ttext ${ORG} -o btxldr.out btxldr.o
+ /usr/libexec/elf/objcopy -S -O binary btxldr.out ${.TARGET}
+.endif
+
+btxldr.o: btxldr.s
+ ${AS} ${AFLAGS} -o ${.TARGET} btxldr.s
+
+clean:
+ rm -f btxldr btxldr.out btxldr.o
diff --git a/sys/boot/i386/btx/btxldr/btxldr.S b/sys/boot/i386/btx/btxldr/btxldr.S
new file mode 100644
index 0000000..2c3fb76
--- /dev/null
+++ b/sys/boot/i386/btx/btxldr/btxldr.S
@@ -0,0 +1,368 @@
+#
+# Copyright (c) 1998 Robert Nordier
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms are freely
+# permitted provided that the above copyright notice and this
+# paragraph and the following disclaimer are duplicated in all
+# such forms.
+#
+# This software is provided "AS IS" and without any express or
+# implied warranties, including, without limitation, the implied
+# warranties of merchantability and fitness for a particular
+# purpose.
+#
+
+# $Id:$
+
+#
+# Prototype BTX loader program, written in a couple of hours. The
+# real thing should probably be more flexible, and in C.
+#
+
+#
+# Memory locations.
+#
+ .set MEM_STUB,0x600 # Real mode stub
+ .set MEM_ESP,0x1000 # New stack pointer
+ .set MEM_TBL,0x5000 # BTX page tables
+ .set MEM_ENTRY,0x9010 # BTX entry point
+ .set MEM_DATA,0x101000 # Data segment
+#
+# Segment selectors.
+#
+ .set SEL_SCODE,0x8 # 4GB code
+ .set SEL_SDATA,0x10 # 4GB data
+ .set SEL_RCODE,0x18 # 64K code
+ .set SEL_RDATA,0x20 # 64K data
+#
+# Paging constants.
+#
+ .set PAG_SIZ,0x1000 # Page size
+ .set PAG_ENT,0x4 # Page entry size
+#
+# Screen constants.
+#
+ .set SCR_MAT,0x7 # Mode/attribute
+ .set SCR_COL,0x50 # Columns per row
+ .set SCR_ROW,0x19 # Rows per screen
+#
+# BIOS Data Area locations.
+#
+ .set BDA_MEM,0x413 # Free memory
+ .set BDA_SCR,0x449 # Video mode
+ .set BDA_POS,0x450 # Cursor position
+#
+# Required by aout gas inadequacy.
+#
+ .set SIZ_STUB,0x1a # Size of stub
+#
+# We expect to be loaded by boot2 at 0x100000.
+#
+ .globl start
+#
+# BTX program loader for ELF clients.
+#
+start: cld # String ops inc
+ movl $m_logo,%esi # Identify
+ call putstr # ourselves
+ movl BDA_MEM,%eax # Get base memory
+ shll $0xa,%eax # in bytes
+ movl %eax,%ebp # Base of user stack
+ movl $m_mem,%esi # Display
+ call hexout # amount of
+ call putstr # base memory
+ lgdt gdtdesc # Load new GDT
+#
+# Relocate caller's arguments.
+#
+ movl $m_esp,%esi # Display
+ movl %esp,%eax # caller's
+ call hexout # stack
+ call putstr # pointer
+ movl $m_args,%esi # Format string
+ leal 0x4(%esp,1),%ebx # First argument
+ movl $0x6,%ecx # Count
+start.1: movl (%ebx),%eax # Get argument and
+ addl $0x4,%ebx # bump pointer
+ call hexout # Display it
+ loop start.1 # Till done
+ call putstr # End message
+ movl $0x48,%ecx # Allocate space
+ subl %ecx,%ebp # for bootinfo
+ movl 0x18(%esp,1),%esi # Source
+ movl %ebp,%edi # Destination
+ rep # Copy
+ movsb # it
+ movl %ebp,0x18(%esp,1) # Update pointer
+ movl $m_rel_bi,%esi # Display
+ movl %ebp,%eax # bootinfo
+ call hexout # relocation
+ call putstr # message
+ movl $0x18,%ecx # Allocate space
+ subl %ecx,%ebp # for arguments
+ leal 0x4(%esp,1),%esi # Source
+ movl %ebp,%edi # Destination
+ rep # Copy
+ movsb # them
+ movl $m_rel_args,%esi # Display
+ movl %ebp,%eax # argument
+ call hexout # relocation
+ call putstr # message
+#
+# Set up BTX kernel.
+#
+ movl $MEM_ESP,%esp # Set up new stack
+ movl $MEM_DATA,%ebx # Data segment
+ movl $m_vers,%esi # Display BTX
+ call putstr # version message
+ movb 0x5(%ebx),%al # Get major version
+ addb $'0',%al # Display
+ call putchr # it
+ movb $'.',%al # And a
+ call putchr # dot
+ movb 0x6(%ebx),%al # Get minor
+ xorb %ah,%ah # version
+ movb $0xa,%dl # Divide
+ divb %dl,%al # by 10
+ addb $'0',%al # Display
+ call putchr # tens
+ movb %ah,%al # Get units
+ addb $'0',%al # Display
+ call putchr # units
+ call putstr # End message
+ movl %ebx,%esi # BTX image
+ movzwl 0x8(%ebx),%edi # Compute
+ orl $PAG_SIZ/PAG_ENT-1,%edi # the
+ incl %edi # BTX
+ shll $0x2,%edi # load
+ addl $MEM_TBL,%edi # address
+ pushl %edi # Save
+ movzwl 0xa(%ebx),%ecx # Image size
+ pushl %ecx # Save
+ rep # Relocate
+ movsb # BTX
+ movl %esi,%ebx # Keep place
+ movl $m_rel_btx,%esi # Restore
+ popl %eax # parameters
+ call hexout # and
+ popl %ebp # display
+ movl %ebp,%eax # the
+ call hexout # relocation
+ call putstr # message
+ addl $PAG_SIZ,%ebp # Display
+ movl $m_base,%esi # the
+ movl %ebp,%eax # user
+ call hexout # base
+ call putstr # address
+#
+# Set up ELF-format client program.
+#
+ cmpl $0x464c457f,(%ebx) # ELF magic number?
+ je start.3 # Yes
+ movl $e_fmt,%esi # Display error
+ call putstr # message
+start.2: jmp start.2 # Hang
+start.3: movl $m_elf,%esi # Display ELF
+ call putstr # message
+ movl $m_segs,%esi # Format string
+ movl $0x2,%edi # Segment count
+ movl 0x1c(%ebx),%edx # Get e_phoff
+ addl %ebx,%edx # To pointer
+ movzwl 0x2c(%ebx),%ecx # Get e_phnum
+start.4: cmpl $0x1,(%edx) # Is p_type PT_LOAD?
+ jne start.6 # No
+ movl 0x4(%edx),%eax # Display
+ call hexout # p_offset
+ movl 0x8(%edx),%eax # Display
+ call hexout # p_vaddr
+ movl 0x10(%edx),%eax # Display
+ call hexout # p_filesz
+ movl 0x14(%edx),%eax # Display
+ call hexout # p_memsz
+ call putstr # End message
+ pushl %esi # Save
+ pushl %edi # working
+ pushl %ecx # registers
+ movl 0x4(%edx),%esi # Get p_offset
+ addl %ebx,%esi # as pointer
+ movl 0x8(%edx),%edi # Get p_vaddr
+ addl %ebp,%edi # as pointer
+ movl 0x10(%edx),%ecx # Get p_filesz
+ rep # Set up
+ movsb # segment
+ movl 0x14(%edx),%ecx # Any bytes
+ subl 0x10(%edx),%ecx # to zero?
+ jz start.5 # No
+ xorb %al,%al # Then
+ rep # zero
+ stosb # them
+start.5: popl %ecx # Restore
+ popl %edi # working
+ popl %esi # registers
+ decl %edi # Segments to do
+ je start.7 # If none
+start.6: addl $0x20,%edx # To next entry
+ loop start.4 # Till done
+start.7: movl $m_done,%esi # Display done
+ call putstr # message
+ movl $start.8,%esi # Real mode stub
+ movl $MEM_STUB,%edi # Destination
+ movl $SIZ_STUB,%ecx # Size
+ rep # Relocate
+ movsb # it
+ ljmp $SEL_RCODE,$MEM_STUB # To 16-bit code
+start.8: xorl %eax,%eax # Data
+ movb $SEL_RDATA,%al # selector
+ movl %eax,%ss # Reload SS
+ movl %eax,%ds # Reset
+ movl %eax,%es # other
+ movl %eax,%fs # segment
+ movl %eax,%gs # limits
+ movl %cr0,%eax # Switch to
+ decl %eax # real
+ movl %eax,%cr0 # mode
+ .byte 0xea # Jump to
+ .word MEM_ENTRY # BTX entry
+ .word 0x0 # point
+start.9:
+#
+# Output message [ESI] followed by EAX in hex.
+#
+hexout: pushl %eax # Save
+ call putstr # Display message
+ popl %eax # Restore
+ pushl %esi # Save
+ pushl %edi # caller's
+ movl $buf,%edi # Buffer
+ pushl %edi # Save
+ call hex32 # To hex
+ xorb %al,%al # Terminate
+ stosb # string
+ popl %esi # Restore
+hexout.1: lodsb # Get a char
+ cmpb $'0',%al # Leading zero?
+ je hexout.1 # Yes
+ testb %al,%al # End of string?
+ jne hexout.2 # No
+ decl %esi # Undo
+hexout.2: decl %esi # Adjust for inc
+ call putstr # Display hex
+ popl %edi # Restore
+ popl %esi # caller's
+ ret # To caller
+#
+# Output zero-terminated string [ESI] to the console.
+#
+putstr.0: call putchr # Output char
+putstr: lodsb # Load char
+ testb %al,%al # End of string?
+ jne putstr.0 # No
+ ret # To caller
+#
+# Output character AL to the console.
+#
+putchr: pusha # Save
+ xorl %ecx,%ecx # Zero for loops
+ movb $SCR_MAT,%ah # Mode/attribute
+ movl $BDA_POS,%ebx # BDA pointer
+ movw (%ebx),%dx # Cursor position
+ movl $0xb8000,%edi # Regen buffer (color)
+ cmpb %ah,BDA_SCR-BDA_POS(%ebx) # Mono mode?
+ jne putchr.1 # No
+ xorw %di,%di # Regen buffer (mono)
+putchr.1: cmpb $0xa,%al # New line?
+ je putchr.2 # Yes
+ xchgl %eax,%ecx # Save char
+ movb $SCR_COL,%al # Columns per row
+ mulb %dh # * row position
+ addb %dl,%al # + column
+ adcb $0x0,%ah # position
+ shll %eax # * 2
+ xchgl %eax,%ecx # Swap char, offset
+ movw %ax,(%edi,%ecx,1) # Write attr:char
+ incl %edx # Bump cursor
+ cmpb $SCR_COL,%dl # Beyond row?
+ jb putchr.3 # No
+putchr.2: xorb %dl,%dl # Zero column
+ incb %dh # Bump row
+putchr.3: cmpb $SCR_ROW,%dh # Beyond screen?
+ jb putchr.4 # No
+ leal 2*SCR_COL(%edi),%esi # New top line
+ movw $(SCR_ROW-1)*SCR_COL/2,%cx # Words to move
+ rep # Scroll
+ movsl # screen
+ movb $' ',%al # Space
+ movb $SCR_COL,%cl # Columns to clear
+ rep # Clear
+ stosw # line
+ movb $SCR_ROW-1,%dh # Bottom line
+putchr.4: movw %dx,(%ebx) # Update position
+ popa # Restore
+ ret # To caller
+#
+# Convert EAX, AX, or AL to hex, saving the result to [EDI].
+#
+hex32: pushl %eax # Save
+ shrl $0x10,%eax # Do upper
+ call hex16 # 16
+ popl %eax # Restore
+hex16: call hex16.1 # Do upper 8
+hex16.1: xchgb %ah,%al # Save/restore
+hex8: pushl %eax # Save
+ shrb $0x4,%al # Do upper
+ call hex8.1 # 4
+ popl %eax # Restore
+hex8.1: andb $0xf,%al # Get lower 4
+ cmpb $0xa,%al # Convert
+ sbbb $0x69,%al # to hex
+ das # digit
+ orb $0x20,%al # To lower case
+ stosb # Save char
+ ret # (Recursive)
+
+ .data
+ .p2align 4
+#
+# Global descriptor table.
+#
+gdt: .word 0x0,0x0,0x0,0x0 # Null entry
+ .word 0xffff,0x0,0x9a00,0xcf # SEL_SCODE
+ .word 0xffff,0x0,0x9200,0xcf # SEL_SDATA
+ .word 0xffff,0x0,0x9a00,0x0 # SEL_RCODE
+ .word 0xffff,0x0,0x9200,0x0 # SEL_RDATA
+gdt.1:
+gdtdesc: .word gdt.1-gdt-1 # Limit
+ .long gdt # Base
+#
+# Messages.
+#
+m_logo: .asciz "\nBTX loader 0.01\n"
+m_mem: .asciz "Starting in protected mode (base mem=\0)\n"
+m_esp: .asciz "Arguments passed (esp=\0):\n"
+m_args: .asciz"<howto="
+ .asciz" bootdev="
+ .asciz" junk="
+ .asciz" "
+ .asciz" "
+ .asciz" bootinfo=\0>\n"
+m_rel_bi: .asciz "Relocated bootinfo (size=48) to \0\n"
+m_rel_args: .asciz "Relocated arguments (size=18) to \0\n"
+m_vers: .asciz "BTX version is \0\n"
+m_rel_btx: .asciz "Relocated kernel (size=\0) to \0\n"
+m_base: .asciz "Client base address is \0\n"
+e_fmt: .asciz "Error: Client format not supported\n"
+m_elf: .asciz "Client format is ELF\n"
+m_segs: .asciz "text segment: offset="
+ .asciz " vaddr="
+ .asciz " filesz="
+ .asciz " memsz=\0\n"
+ .asciz "data segment: offset="
+ .asciz " vaddr="
+ .asciz " filesz="
+ .asciz " memsz=\0\n"
+m_done: .asciz "Loading complete\n"
+#
+# Uninitialized data area.
+#
+buf: # Scratch buffer
diff --git a/sys/boot/i386/btx/btxldr/btxldr.s b/sys/boot/i386/btx/btxldr/btxldr.s
new file mode 100644
index 0000000..2c3fb76
--- /dev/null
+++ b/sys/boot/i386/btx/btxldr/btxldr.s
@@ -0,0 +1,368 @@
+#
+# Copyright (c) 1998 Robert Nordier
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms are freely
+# permitted provided that the above copyright notice and this
+# paragraph and the following disclaimer are duplicated in all
+# such forms.
+#
+# This software is provided "AS IS" and without any express or
+# implied warranties, including, without limitation, the implied
+# warranties of merchantability and fitness for a particular
+# purpose.
+#
+
+# $Id:$
+
+#
+# Prototype BTX loader program, written in a couple of hours. The
+# real thing should probably be more flexible, and in C.
+#
+
+#
+# Memory locations.
+#
+ .set MEM_STUB,0x600 # Real mode stub
+ .set MEM_ESP,0x1000 # New stack pointer
+ .set MEM_TBL,0x5000 # BTX page tables
+ .set MEM_ENTRY,0x9010 # BTX entry point
+ .set MEM_DATA,0x101000 # Data segment
+#
+# Segment selectors.
+#
+ .set SEL_SCODE,0x8 # 4GB code
+ .set SEL_SDATA,0x10 # 4GB data
+ .set SEL_RCODE,0x18 # 64K code
+ .set SEL_RDATA,0x20 # 64K data
+#
+# Paging constants.
+#
+ .set PAG_SIZ,0x1000 # Page size
+ .set PAG_ENT,0x4 # Page entry size
+#
+# Screen constants.
+#
+ .set SCR_MAT,0x7 # Mode/attribute
+ .set SCR_COL,0x50 # Columns per row
+ .set SCR_ROW,0x19 # Rows per screen
+#
+# BIOS Data Area locations.
+#
+ .set BDA_MEM,0x413 # Free memory
+ .set BDA_SCR,0x449 # Video mode
+ .set BDA_POS,0x450 # Cursor position
+#
+# Required by aout gas inadequacy.
+#
+ .set SIZ_STUB,0x1a # Size of stub
+#
+# We expect to be loaded by boot2 at 0x100000.
+#
+ .globl start
+#
+# BTX program loader for ELF clients.
+#
+start: cld # String ops inc
+ movl $m_logo,%esi # Identify
+ call putstr # ourselves
+ movl BDA_MEM,%eax # Get base memory
+ shll $0xa,%eax # in bytes
+ movl %eax,%ebp # Base of user stack
+ movl $m_mem,%esi # Display
+ call hexout # amount of
+ call putstr # base memory
+ lgdt gdtdesc # Load new GDT
+#
+# Relocate caller's arguments.
+#
+ movl $m_esp,%esi # Display
+ movl %esp,%eax # caller's
+ call hexout # stack
+ call putstr # pointer
+ movl $m_args,%esi # Format string
+ leal 0x4(%esp,1),%ebx # First argument
+ movl $0x6,%ecx # Count
+start.1: movl (%ebx),%eax # Get argument and
+ addl $0x4,%ebx # bump pointer
+ call hexout # Display it
+ loop start.1 # Till done
+ call putstr # End message
+ movl $0x48,%ecx # Allocate space
+ subl %ecx,%ebp # for bootinfo
+ movl 0x18(%esp,1),%esi # Source
+ movl %ebp,%edi # Destination
+ rep # Copy
+ movsb # it
+ movl %ebp,0x18(%esp,1) # Update pointer
+ movl $m_rel_bi,%esi # Display
+ movl %ebp,%eax # bootinfo
+ call hexout # relocation
+ call putstr # message
+ movl $0x18,%ecx # Allocate space
+ subl %ecx,%ebp # for arguments
+ leal 0x4(%esp,1),%esi # Source
+ movl %ebp,%edi # Destination
+ rep # Copy
+ movsb # them
+ movl $m_rel_args,%esi # Display
+ movl %ebp,%eax # argument
+ call hexout # relocation
+ call putstr # message
+#
+# Set up BTX kernel.
+#
+ movl $MEM_ESP,%esp # Set up new stack
+ movl $MEM_DATA,%ebx # Data segment
+ movl $m_vers,%esi # Display BTX
+ call putstr # version message
+ movb 0x5(%ebx),%al # Get major version
+ addb $'0',%al # Display
+ call putchr # it
+ movb $'.',%al # And a
+ call putchr # dot
+ movb 0x6(%ebx),%al # Get minor
+ xorb %ah,%ah # version
+ movb $0xa,%dl # Divide
+ divb %dl,%al # by 10
+ addb $'0',%al # Display
+ call putchr # tens
+ movb %ah,%al # Get units
+ addb $'0',%al # Display
+ call putchr # units
+ call putstr # End message
+ movl %ebx,%esi # BTX image
+ movzwl 0x8(%ebx),%edi # Compute
+ orl $PAG_SIZ/PAG_ENT-1,%edi # the
+ incl %edi # BTX
+ shll $0x2,%edi # load
+ addl $MEM_TBL,%edi # address
+ pushl %edi # Save
+ movzwl 0xa(%ebx),%ecx # Image size
+ pushl %ecx # Save
+ rep # Relocate
+ movsb # BTX
+ movl %esi,%ebx # Keep place
+ movl $m_rel_btx,%esi # Restore
+ popl %eax # parameters
+ call hexout # and
+ popl %ebp # display
+ movl %ebp,%eax # the
+ call hexout # relocation
+ call putstr # message
+ addl $PAG_SIZ,%ebp # Display
+ movl $m_base,%esi # the
+ movl %ebp,%eax # user
+ call hexout # base
+ call putstr # address
+#
+# Set up ELF-format client program.
+#
+ cmpl $0x464c457f,(%ebx) # ELF magic number?
+ je start.3 # Yes
+ movl $e_fmt,%esi # Display error
+ call putstr # message
+start.2: jmp start.2 # Hang
+start.3: movl $m_elf,%esi # Display ELF
+ call putstr # message
+ movl $m_segs,%esi # Format string
+ movl $0x2,%edi # Segment count
+ movl 0x1c(%ebx),%edx # Get e_phoff
+ addl %ebx,%edx # To pointer
+ movzwl 0x2c(%ebx),%ecx # Get e_phnum
+start.4: cmpl $0x1,(%edx) # Is p_type PT_LOAD?
+ jne start.6 # No
+ movl 0x4(%edx),%eax # Display
+ call hexout # p_offset
+ movl 0x8(%edx),%eax # Display
+ call hexout # p_vaddr
+ movl 0x10(%edx),%eax # Display
+ call hexout # p_filesz
+ movl 0x14(%edx),%eax # Display
+ call hexout # p_memsz
+ call putstr # End message
+ pushl %esi # Save
+ pushl %edi # working
+ pushl %ecx # registers
+ movl 0x4(%edx),%esi # Get p_offset
+ addl %ebx,%esi # as pointer
+ movl 0x8(%edx),%edi # Get p_vaddr
+ addl %ebp,%edi # as pointer
+ movl 0x10(%edx),%ecx # Get p_filesz
+ rep # Set up
+ movsb # segment
+ movl 0x14(%edx),%ecx # Any bytes
+ subl 0x10(%edx),%ecx # to zero?
+ jz start.5 # No
+ xorb %al,%al # Then
+ rep # zero
+ stosb # them
+start.5: popl %ecx # Restore
+ popl %edi # working
+ popl %esi # registers
+ decl %edi # Segments to do
+ je start.7 # If none
+start.6: addl $0x20,%edx # To next entry
+ loop start.4 # Till done
+start.7: movl $m_done,%esi # Display done
+ call putstr # message
+ movl $start.8,%esi # Real mode stub
+ movl $MEM_STUB,%edi # Destination
+ movl $SIZ_STUB,%ecx # Size
+ rep # Relocate
+ movsb # it
+ ljmp $SEL_RCODE,$MEM_STUB # To 16-bit code
+start.8: xorl %eax,%eax # Data
+ movb $SEL_RDATA,%al # selector
+ movl %eax,%ss # Reload SS
+ movl %eax,%ds # Reset
+ movl %eax,%es # other
+ movl %eax,%fs # segment
+ movl %eax,%gs # limits
+ movl %cr0,%eax # Switch to
+ decl %eax # real
+ movl %eax,%cr0 # mode
+ .byte 0xea # Jump to
+ .word MEM_ENTRY # BTX entry
+ .word 0x0 # point
+start.9:
+#
+# Output message [ESI] followed by EAX in hex.
+#
+hexout: pushl %eax # Save
+ call putstr # Display message
+ popl %eax # Restore
+ pushl %esi # Save
+ pushl %edi # caller's
+ movl $buf,%edi # Buffer
+ pushl %edi # Save
+ call hex32 # To hex
+ xorb %al,%al # Terminate
+ stosb # string
+ popl %esi # Restore
+hexout.1: lodsb # Get a char
+ cmpb $'0',%al # Leading zero?
+ je hexout.1 # Yes
+ testb %al,%al # End of string?
+ jne hexout.2 # No
+ decl %esi # Undo
+hexout.2: decl %esi # Adjust for inc
+ call putstr # Display hex
+ popl %edi # Restore
+ popl %esi # caller's
+ ret # To caller
+#
+# Output zero-terminated string [ESI] to the console.
+#
+putstr.0: call putchr # Output char
+putstr: lodsb # Load char
+ testb %al,%al # End of string?
+ jne putstr.0 # No
+ ret # To caller
+#
+# Output character AL to the console.
+#
+putchr: pusha # Save
+ xorl %ecx,%ecx # Zero for loops
+ movb $SCR_MAT,%ah # Mode/attribute
+ movl $BDA_POS,%ebx # BDA pointer
+ movw (%ebx),%dx # Cursor position
+ movl $0xb8000,%edi # Regen buffer (color)
+ cmpb %ah,BDA_SCR-BDA_POS(%ebx) # Mono mode?
+ jne putchr.1 # No
+ xorw %di,%di # Regen buffer (mono)
+putchr.1: cmpb $0xa,%al # New line?
+ je putchr.2 # Yes
+ xchgl %eax,%ecx # Save char
+ movb $SCR_COL,%al # Columns per row
+ mulb %dh # * row position
+ addb %dl,%al # + column
+ adcb $0x0,%ah # position
+ shll %eax # * 2
+ xchgl %eax,%ecx # Swap char, offset
+ movw %ax,(%edi,%ecx,1) # Write attr:char
+ incl %edx # Bump cursor
+ cmpb $SCR_COL,%dl # Beyond row?
+ jb putchr.3 # No
+putchr.2: xorb %dl,%dl # Zero column
+ incb %dh # Bump row
+putchr.3: cmpb $SCR_ROW,%dh # Beyond screen?
+ jb putchr.4 # No
+ leal 2*SCR_COL(%edi),%esi # New top line
+ movw $(SCR_ROW-1)*SCR_COL/2,%cx # Words to move
+ rep # Scroll
+ movsl # screen
+ movb $' ',%al # Space
+ movb $SCR_COL,%cl # Columns to clear
+ rep # Clear
+ stosw # line
+ movb $SCR_ROW-1,%dh # Bottom line
+putchr.4: movw %dx,(%ebx) # Update position
+ popa # Restore
+ ret # To caller
+#
+# Convert EAX, AX, or AL to hex, saving the result to [EDI].
+#
+hex32: pushl %eax # Save
+ shrl $0x10,%eax # Do upper
+ call hex16 # 16
+ popl %eax # Restore
+hex16: call hex16.1 # Do upper 8
+hex16.1: xchgb %ah,%al # Save/restore
+hex8: pushl %eax # Save
+ shrb $0x4,%al # Do upper
+ call hex8.1 # 4
+ popl %eax # Restore
+hex8.1: andb $0xf,%al # Get lower 4
+ cmpb $0xa,%al # Convert
+ sbbb $0x69,%al # to hex
+ das # digit
+ orb $0x20,%al # To lower case
+ stosb # Save char
+ ret # (Recursive)
+
+ .data
+ .p2align 4
+#
+# Global descriptor table.
+#
+gdt: .word 0x0,0x0,0x0,0x0 # Null entry
+ .word 0xffff,0x0,0x9a00,0xcf # SEL_SCODE
+ .word 0xffff,0x0,0x9200,0xcf # SEL_SDATA
+ .word 0xffff,0x0,0x9a00,0x0 # SEL_RCODE
+ .word 0xffff,0x0,0x9200,0x0 # SEL_RDATA
+gdt.1:
+gdtdesc: .word gdt.1-gdt-1 # Limit
+ .long gdt # Base
+#
+# Messages.
+#
+m_logo: .asciz "\nBTX loader 0.01\n"
+m_mem: .asciz "Starting in protected mode (base mem=\0)\n"
+m_esp: .asciz "Arguments passed (esp=\0):\n"
+m_args: .asciz"<howto="
+ .asciz" bootdev="
+ .asciz" junk="
+ .asciz" "
+ .asciz" "
+ .asciz" bootinfo=\0>\n"
+m_rel_bi: .asciz "Relocated bootinfo (size=48) to \0\n"
+m_rel_args: .asciz "Relocated arguments (size=18) to \0\n"
+m_vers: .asciz "BTX version is \0\n"
+m_rel_btx: .asciz "Relocated kernel (size=\0) to \0\n"
+m_base: .asciz "Client base address is \0\n"
+e_fmt: .asciz "Error: Client format not supported\n"
+m_elf: .asciz "Client format is ELF\n"
+m_segs: .asciz "text segment: offset="
+ .asciz " vaddr="
+ .asciz " filesz="
+ .asciz " memsz=\0\n"
+ .asciz "data segment: offset="
+ .asciz " vaddr="
+ .asciz " filesz="
+ .asciz " memsz=\0\n"
+m_done: .asciz "Loading complete\n"
+#
+# Uninitialized data area.
+#
+buf: # Scratch buffer
OpenPOWER on IntegriCloud