2 * Copyright (c) 1998 Robert Nordier
5 * Redistribution and use in source and binary forms are freely
6 * permitted provided that the above copyright notice and this
7 * paragraph and the following disclaimer are duplicated in all
10 * This software is provided "AS IS" and without any express or
11 * implied warranties, including, without limitation, the implied
12 * warranties of merchantability and fitness for a particular
15 * $FreeBSD: src/sys/boot/i386/btx/btxldr/Makefile,v 1.17 2004/04/27 19:45:16 ru Exp $
16 * $DragonFly: src/sys/boot/i386/btx/btxldr/Attic/btxldr.S,v 1.2 2004/07/19 01:25:01 dillon Exp $
20 * Prototype BTX loader program, written in a couple of hours. The
21 * real thing should probably be more flexible, and in C.
24 #include "../../bootasm.h"
28 .set MEM_DATA,start+0x1000 # Data segment
32 .set SEL_SCODE,0x8 # 4GB code
33 .set SEL_SDATA,0x10 # 4GB data
34 .set SEL_RCODE,0x18 # 64K code
35 .set SEL_RDATA,0x20 # 64K data
39 .set PAG_SIZ,0x1000 # Page size
40 .set PAG_ENT,0x4 # Page entry size
44 .set SCR_MAT,0x7 # Mode/attribute
45 .set SCR_COL,0x50 # Columns per row
46 .set SCR_ROW,0x19 # Rows per screen
48 * Required by aout gas inadequacy.
50 .set SIZ_STUB,0x1a # Size of stub
52 * We expect to be loaded by boot2 at the origin defined in ./Makefile.
56 * BTX program loader for ELF clients.
58 start: cld # String ops inc
59 movl $m_logo,%esi # Identify
60 call putstr # ourselves
61 movzwl BDA_MEM,%eax # Get base memory
62 shll $0xa,%eax # Convert to bytes
63 movl %eax,%ebp # Base of user stack
65 movl $m_mem,%esi # Display
66 call hexout # amount of
67 call putstr # base memory
69 lgdt gdtdesc # Load new GDT
71 * Relocate caller's arguments.
74 movl $m_esp,%esi # Display
75 movl %esp,%eax # caller
78 movl $m_args,%esi # Format string
79 leal 0x4(%esp,1),%ebx # First argument
80 movl $0x6,%ecx # Count
81 start.1: movl (%ebx),%eax # Get argument and
82 addl $0x4,%ebx # bump pointer
83 call hexout # Display it
84 loop start.1 # Till done
85 call putstr # End message
88 * Arguments: (entry, boothowto, bootdev, 0, 0, 0, bootinfo)
89 * 0x00, 0x04, 0x08, 0x18
91 * sizeof(bootinfo) == 0x48 (BOOTINFO_SIZE)
92 * sizeof arguments == 0x18 (MEM_ARG_SIZE)
93 * total arguments == 0x60 bytes (USR_ARGOFFSET)
96 movl $BOOTINFO_SIZE,%ecx # Allocate space
97 subl %ecx,%ebp # for bootinfo
98 movl 0x18(%esp,1),%esi # Source: bootinfo
99 cmpl $0x0, %esi # If the bootinfo pointer
100 je start_null_bi # is null, do not copy it
101 movl %ebp,%edi # Destination
104 movl %ebp,0x18(%esp,1) # Update pointer
105 #ifdef BTXLDR_VERBOSE
106 movl $m_rel_bi,%esi # Display
107 movl %ebp,%eax # bootinfo
108 call hexout # relocation
109 call putstr # message
111 start_null_bi: movl $0x18,%ecx # Allocate space
112 subl %ecx,%ebp # for arguments
113 leal 0x4(%esp,1),%esi # Source
114 movl %ebp,%edi # Destination
117 #ifdef BTXLDR_VERBOSE
118 movl $m_rel_args,%esi # Display
119 movl %ebp,%eax # argument
120 call hexout # relocation
121 call putstr # message
126 movl $MEM_BTX_ESP,%esp # Set up new stack
127 movl $MEM_DATA,%ebx # Data segment
128 movl $m_vers,%esi # Display BTX
129 call putstr # version message
130 movb 0x5(%ebx),%al # Get major version
131 addb $'0',%al # Display
133 movb $'.',%al # And a
135 movb 0x6(%ebx),%al # Get minor
136 xorb %ah,%ah # version
137 movb $0xa,%dl # Divide
139 addb $'0',%al # Display
141 movb %ah,%al # Get units
142 addb $'0',%al # Display
144 call putstr # End message
145 movl %ebx,%esi # BTX image
146 movzwl 0x8(%ebx),%edi # Compute
147 orl $PAG_SIZ/PAG_ENT-1,%edi # the
149 shll $0x2,%edi # load
150 addl $MEM_BTX_TBL,%edi # address
151 pushl %edi # Save load address
152 movzwl 0xa(%ebx),%ecx # Image size
153 #ifdef BTXLDR_VERBOSE
154 pushl %ecx # Save image size
158 movl %esi,%ebx # Keep place
159 #ifdef BTXLDR_VERBOSE
160 movl $m_rel_btx,%esi # Restore
161 popl %eax # parameters
165 #ifdef BTXLDR_VERBOSE
167 call hexout # relocation
168 call putstr # message
170 addl $PAG_SIZ,%ebp # Display
171 #ifdef BTXLDR_VERBOSE
172 movl $m_base,%esi # the
173 movl %ebp,%eax # user
175 call putstr # address
178 * Set up ELF-format client program.
180 cmpl $0x464c457f,(%ebx) # ELF magic number?
182 movl $e_fmt,%esi # Display error
183 call putstr # message
184 start.2: jmp start.2 # Hang
186 #ifdef BTXLDR_VERBOSE
187 movl $m_elf,%esi # Display ELF
188 call putstr # message
189 movl $m_segs,%esi # Format string
191 movl $0x2,%edi # Segment count
192 movl 0x1c(%ebx),%edx # Get e_phoff
193 addl %ebx,%edx # To pointer
194 movzwl 0x2c(%ebx),%ecx # Get e_phnum
195 start.4: cmpl $0x1,(%edx) # Is p_type PT_LOAD?
197 #ifdef BTXLDR_VERBOSE
198 movl 0x4(%edx),%eax # Display
199 call hexout # p_offset
200 movl 0x8(%edx),%eax # Display
201 call hexout # p_vaddr
202 movl 0x10(%edx),%eax # Display
203 call hexout # p_filesz
204 movl 0x14(%edx),%eax # Display
205 call hexout # p_memsz
206 call putstr # End message
210 pushl %ecx # registers
211 movl 0x4(%edx),%esi # Get p_offset
212 addl %ebx,%esi # as pointer
213 movl 0x8(%edx),%edi # Get p_vaddr
214 addl %ebp,%edi # as pointer
215 movl 0x10(%edx),%ecx # Get p_filesz
218 movl 0x14(%edx),%ecx # Any bytes
219 subl 0x10(%edx),%ecx # to zero?
224 start.5: popl %ecx # Restore
226 popl %esi # registers
227 decl %edi # Segments to do
229 start.6: addl $0x20,%edx # To next entry
230 loop start.4 # Till done
232 #ifdef BTXLDR_VERBOSE
233 movl $m_done,%esi # Display done
234 call putstr # message
236 movl $start.8,%esi # Real mode stub
237 movl $BOOT0_ORIGIN,%edi # Destination
238 movl $start.9-start.8,%ecx # Size
241 ljmp $SEL_RCODE,$BOOT0_ORIGIN # To 16-bit code
243 start.8: xorw %ax,%ax # Data
244 movb $SEL_RDATA,%al # selector
245 movw %ax,%ss # Reload SS
248 movw %ax,%fs # segment
249 movw %ax,%gs # limits
250 movl %cr0,%eax # Switch to
252 movl %eax,%cr0 # mode
253 ljmp $0,$MEM_BTX_ENTRY # Jump to BTX entry point
257 * Output message [ESI] followed by EAX in hex.
259 hexout: pushl %eax # Save
260 call putstr # Display message
264 movl $buf,%edi # Buffer
267 xorb %al,%al # Terminate
270 hexout.1: lodsb # Get a char
271 cmpb $'0',%al # Leading zero?
273 testb %al,%al # End of string?
276 hexout.2: decl %esi # Adjust for inc
277 call putstr # Display hex
282 * Output zero-terminated string [ESI] to the console.
284 putstr.0: call putchr # Output char
285 putstr: lodsb # Load char
286 testb %al,%al # End of string?
290 * Output character AL to the console.
293 xorl %ecx,%ecx # Zero for loops
294 movb $SCR_MAT,%ah # Mode/attribute
295 movl $BDA_POS,%ebx # BDA pointer
296 movw (%ebx),%dx # Cursor position
297 movl $0xb8000,%edi # Regen buffer (color)
298 cmpb %ah,BDA_SCR-BDA_POS(%ebx) # Mono mode?
300 xorw %di,%di # Regen buffer (mono)
301 putchr.1: cmpb $0xa,%al # New line?
303 xchgl %eax,%ecx # Save char
304 movb $SCR_COL,%al # Columns per row
305 mulb %dh # * row position
306 addb %dl,%al # + column
307 adcb $0x0,%ah # position
309 xchgl %eax,%ecx # Swap char, offset
310 movw %ax,(%edi,%ecx,1) # Write attr:char
311 incl %edx # Bump cursor
312 cmpb $SCR_COL,%dl # Beyond row?
314 putchr.2: xorb %dl,%dl # Zero column
316 putchr.3: cmpb $SCR_ROW,%dh # Beyond screen?
318 leal 2*SCR_COL(%edi),%esi # New top line
319 movw $(SCR_ROW-1)*SCR_COL/2,%cx # Words to move
322 movb $' ',%al # Space
323 movb $SCR_COL,%cl # Columns to clear
326 movb $SCR_ROW-1,%dh # Bottom line
327 putchr.4: movw %dx,(%ebx) # Update position
331 * Convert EAX, AX, or AL to hex, saving the result to [EDI].
333 hex32: pushl %eax # Save
334 shrl $0x10,%eax # Do upper
337 hex16: call hex16.1 # Do upper 8
338 hex16.1: xchgb %ah,%al # Save/restore
339 hex8: pushl %eax # Save
340 shrb $0x4,%al # Do upper
343 hex8.1: andb $0xf,%al # Get lower 4
344 cmpb $0xa,%al # Convert
345 sbbb $0x69,%al # to hex
347 orb $0x20,%al # To lower case
354 * Global descriptor table.
356 gdt: .word 0x0,0x0,0x0,0x0 # Null entry
357 .word 0xffff,0x0,0x9a00,0xcf # SEL_SCODE
358 .word 0xffff,0x0,0x9200,0xcf # SEL_SDATA
359 .word 0xffff,0x0,0x9a00,0x0 # SEL_RCODE
360 .word 0xffff,0x0,0x9200,0x0 # SEL_RDATA
362 gdtdesc: .word gdt.1-gdt-1 # Limit
367 m_logo: .asciz " \nBTX loader 1.00 "
368 m_vers: .asciz "BTX version is \0\n"
369 e_fmt: .asciz "Error: Client format not supported\n"
370 #ifdef BTXLDR_VERBOSE
371 m_mem: .asciz "Starting in protected mode (base mem=\0)\n"
372 m_esp: .asciz "Arguments passed (esp=\0):\n"
373 m_args: .asciz"<howto="
378 .asciz" bootinfo=\0>\n"
379 m_rel_bi: .asciz "Relocated bootinfo (size=48) to \0\n"
380 m_rel_args: .asciz "Relocated arguments (size=18) to \0\n"
381 m_rel_btx: .asciz "Relocated kernel (size=\0) to \0\n"
382 m_base: .asciz "Client base address is \0\n"
383 m_elf: .asciz "Client format is ELF\n"
384 m_segs: .asciz "text segment: offset="
388 .asciz "data segment: offset="
392 m_done: .asciz "Loading complete\n"
395 * Uninitialized data area.
397 buf: # Scratch buffer