mirror of
				https://github.com/xcat2/xNBA.git
				synced 2025-11-04 05:12:33 +00:00 
			
		
		
		
	[PXE] Add PMM support to romprefix.S (untested)
ROM initialisation vector now attempts to allocate a 2MB block using PMM. If successful, it copies the ROM image to this block, then shrinks the ROM image to allow for more option ROMs. If unsuccessful, it leaves the ROM as-is. ROM BEV now attempts to return to the BIOS, resorting to INT 18 only if the BIOS stack has been corrupted.
This commit is contained in:
		@@ -17,6 +17,10 @@
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
	.arch i386
 | 
			
		||||
	.section ".prefix.lib", "awx", @progbits
 | 
			
		||||
	.section ".data16", "aw", @progbits
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * High memory temporary load address
 | 
			
		||||
 *
 | 
			
		||||
@@ -27,25 +31,18 @@
 | 
			
		||||
 * We use the start of an even megabyte so that we don't have to worry
 | 
			
		||||
 * about the current state of the A20 line.
 | 
			
		||||
 *
 | 
			
		||||
 * We use 4MB rather than 2MB because there is at least one commercial
 | 
			
		||||
 * PXE ROM ("Broadcom UNDI, PXE-2.1 (build 082) v2.0.4") which stores
 | 
			
		||||
 * data required by the UNDI ROM loader (yes, the ROM loader; that's
 | 
			
		||||
 * the component which should be impossible to damage short of
 | 
			
		||||
 * screwing with the MMU) around the 2MB mark.  Sadly, this is not a
 | 
			
		||||
 * joke.
 | 
			
		||||
 *
 | 
			
		||||
 * We use 4MB rather than 2MB because some PXE stack / PMM BIOS
 | 
			
		||||
 * combinations are known to place data required by other UNDI ROMs
 | 
			
		||||
 * loader around the 2MB mark.
 | 
			
		||||
 */
 | 
			
		||||
#define HIGHMEM_LOADPOINT ( 4 << 20 )
 | 
			
		||||
	.globl	HIGHMEM_LOADPOINT
 | 
			
		||||
	.equ	HIGHMEM_LOADPOINT, ( 4 << 20 )
 | 
			
		||||
 | 
			
		||||
/* Image compression enabled */
 | 
			
		||||
#define COMPRESS 1
 | 
			
		||||
 | 
			
		||||
#define CR0_PE 1
 | 
			
		||||
 | 
			
		||||
	.arch i386
 | 
			
		||||
	.section ".prefix.lib", "awx", @progbits
 | 
			
		||||
	.section ".data16", "aw", @progbits
 | 
			
		||||
 | 
			
		||||
/****************************************************************************
 | 
			
		||||
 * pm_call (real-mode near call)
 | 
			
		||||
 *
 | 
			
		||||
@@ -223,12 +220,15 @@ copy_bytes:
 | 
			
		||||
 * Returns:
 | 
			
		||||
 *   %ds:esi : next source address (will be a multiple of 16)
 | 
			
		||||
 * Corrupts:
 | 
			
		||||
 *   %edi, %ecx, %edx
 | 
			
		||||
 *   %ecx, %edx
 | 
			
		||||
 ****************************************************************************
 | 
			
		||||
 */
 | 
			
		||||
	.section ".prefix.lib"
 | 
			
		||||
	.code16
 | 
			
		||||
install_block:
 | 
			
		||||
	/* Preserve registers */
 | 
			
		||||
	pushl	%edi
 | 
			
		||||
	
 | 
			
		||||
#if COMPRESS
 | 
			
		||||
	/* Decompress source to destination */
 | 
			
		||||
	call	decompress16
 | 
			
		||||
@@ -249,6 +249,8 @@ install_block:
 | 
			
		||||
	addl	$0xf, %esi
 | 
			
		||||
	andl	$~0xf, %esi
 | 
			
		||||
 | 
			
		||||
	/* Restore registers and return */
 | 
			
		||||
	popl	%edi
 | 
			
		||||
	ret
 | 
			
		||||
	.size install_block, . - install_block
 | 
			
		||||
	
 | 
			
		||||
@@ -270,6 +272,7 @@ install_block:
 | 
			
		||||
 */
 | 
			
		||||
	.section ".prefix.lib"
 | 
			
		||||
	.code16
 | 
			
		||||
	.globl	alloc_basemem
 | 
			
		||||
alloc_basemem:
 | 
			
		||||
	/* FBMS => %ax as segment address */
 | 
			
		||||
	movw	$0x40, %ax
 | 
			
		||||
@@ -308,13 +311,14 @@ alloc_basemem:
 | 
			
		||||
 * Returns:
 | 
			
		||||
 *   %esi : next source physical address (will be a multiple of 16)
 | 
			
		||||
 * Corrupts:
 | 
			
		||||
 *   %edi, %ecx, %edx
 | 
			
		||||
 *   %ecx, %edx
 | 
			
		||||
 ****************************************************************************
 | 
			
		||||
 */
 | 
			
		||||
	.section ".prefix.lib"
 | 
			
		||||
	.code16
 | 
			
		||||
install_basemem:
 | 
			
		||||
	/* Preserve registers */
 | 
			
		||||
	pushl	%edi
 | 
			
		||||
	pushw	%ds
 | 
			
		||||
 | 
			
		||||
	/* Preserve original %esi */
 | 
			
		||||
@@ -335,6 +339,7 @@ install_basemem:
 | 
			
		||||
 | 
			
		||||
	/* Restore registers */
 | 
			
		||||
	popw	%ds
 | 
			
		||||
	popl	%edi
 | 
			
		||||
	ret
 | 
			
		||||
	.size install_basemem, . - install_basemem
 | 
			
		||||
 | 
			
		||||
@@ -351,7 +356,7 @@ install_basemem:
 | 
			
		||||
 * Returns:
 | 
			
		||||
 *   %esi : next source physical address (will be a multiple of 16)
 | 
			
		||||
 * Corrupts:
 | 
			
		||||
 *   %edi, %ecx, %edx
 | 
			
		||||
 *   %ecx, %edx
 | 
			
		||||
 ****************************************************************************
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
@@ -376,17 +381,14 @@ install_highmem:
 | 
			
		||||
	
 | 
			
		||||
/****************************************************************************
 | 
			
		||||
 * install (real-mode near call)
 | 
			
		||||
 * install_prealloc (real-mode near call)
 | 
			
		||||
 *
 | 
			
		||||
 * Install all text and data segments.
 | 
			
		||||
 *
 | 
			
		||||
 * Parameters:
 | 
			
		||||
 *   %ax : .text16 segment address (install_prealloc only)
 | 
			
		||||
 *   %bx : .data16 segment address (install_prealloc only)
 | 
			
		||||
 *   none
 | 
			
		||||
 * Returns:
 | 
			
		||||
 *   %ax : .text16 segment address
 | 
			
		||||
 *   %bx : .data16 segment address
 | 
			
		||||
 *   %edi : .text physical address (if applicable)
 | 
			
		||||
 *   %ax  : .text16 segment address
 | 
			
		||||
 *   %bx  : .data16 segment address
 | 
			
		||||
 * Corrupts:
 | 
			
		||||
 *   none
 | 
			
		||||
 ****************************************************************************
 | 
			
		||||
@@ -395,26 +397,55 @@ install_highmem:
 | 
			
		||||
	.code16
 | 
			
		||||
	.globl install
 | 
			
		||||
install:
 | 
			
		||||
	/* Preserve registers */
 | 
			
		||||
	pushl	%esi
 | 
			
		||||
	pushl	%edi
 | 
			
		||||
	/* Allocate space for .text16 and .data16 */
 | 
			
		||||
	call	alloc_basemem
 | 
			
		||||
	/* Image source = %cs:0000 */
 | 
			
		||||
	xorl	%esi, %esi
 | 
			
		||||
	/* Image destination = HIGHMEM_LOADPOINT */
 | 
			
		||||
	movl	$HIGHMEM_LOADPOINT, %edi
 | 
			
		||||
	/* Install text and data segments */
 | 
			
		||||
	call	install_prealloc
 | 
			
		||||
	/* Restore registers and return */
 | 
			
		||||
	popl	%edi
 | 
			
		||||
	popl	%esi
 | 
			
		||||
	ret
 | 
			
		||||
	.size install, . - install
 | 
			
		||||
 | 
			
		||||
/****************************************************************************
 | 
			
		||||
 * install_prealloc (real-mode near call)
 | 
			
		||||
 *
 | 
			
		||||
 * Install all text and data segments.
 | 
			
		||||
 *
 | 
			
		||||
 * Parameters:
 | 
			
		||||
 *   %ax  : .text16 segment address
 | 
			
		||||
 *   %bx  : .data16 segment address
 | 
			
		||||
 *   %esi : Image source physical address (or zero for %cs:0000)
 | 
			
		||||
 *   %edi : Decompression temporary area physical address
 | 
			
		||||
 * Corrupts:
 | 
			
		||||
 *   none
 | 
			
		||||
 ****************************************************************************
 | 
			
		||||
 */
 | 
			
		||||
	.section ".prefix.lib"
 | 
			
		||||
	.code16
 | 
			
		||||
	.globl install_prealloc
 | 
			
		||||
install_prealloc:
 | 
			
		||||
	/* Save registers */
 | 
			
		||||
	pushal
 | 
			
		||||
	pushw	%ds
 | 
			
		||||
	pushw	%es
 | 
			
		||||
	pushl	%esi
 | 
			
		||||
	pushl	%ecx
 | 
			
		||||
	pushl	%edx
 | 
			
		||||
 | 
			
		||||
	/* Sanity: clear the direction flag asap */
 | 
			
		||||
	cld
 | 
			
		||||
 | 
			
		||||
	/* Calculate physical address of payload (i.e. first source) */
 | 
			
		||||
	xorl	%esi, %esi
 | 
			
		||||
	testl	%esi, %esi
 | 
			
		||||
	jnz	1f
 | 
			
		||||
	movw	%cs, %si
 | 
			
		||||
	shll	$4, %esi
 | 
			
		||||
	addl	$_payload_offset, %esi
 | 
			
		||||
1:	addl	$_payload_offset, %esi
 | 
			
		||||
 | 
			
		||||
	/* Install .text16 */
 | 
			
		||||
	movw	%ax, %es
 | 
			
		||||
@@ -440,7 +471,6 @@ install_prealloc:
 | 
			
		||||
	 * prior to reading the E820 memory map and relocating
 | 
			
		||||
	 * properly.
 | 
			
		||||
	 */
 | 
			
		||||
	movl	$HIGHMEM_LOADPOINT, %edi
 | 
			
		||||
	movl	$_textdata_progbits_size, %ecx
 | 
			
		||||
	movl	$_textdata_size, %edx
 | 
			
		||||
	pushl	%edi
 | 
			
		||||
@@ -473,11 +503,9 @@ install_prealloc:
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
	/* Restore registers */
 | 
			
		||||
	popl	%edx
 | 
			
		||||
	popl	%ecx
 | 
			
		||||
	popl	%esi
 | 
			
		||||
	popw	%es
 | 
			
		||||
	popw	%ds
 | 
			
		||||
	popal
 | 
			
		||||
	ret
 | 
			
		||||
	.size install_prealloc, . - install_prealloc
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,10 @@
 | 
			
		||||
 * table so using a noticeable amount of stack space is a no-no.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define PNP_SIGNATURE ( '$' + ( 'P' << 8 ) + ( 'n' << 16 ) + ( 'P' << 24 ) )
 | 
			
		||||
#define PMM_SIGNATURE ( '$' + ( 'P' << 8 ) + ( 'M' << 16 ) + ( 'M' << 24 ) )
 | 
			
		||||
#define STACK_MAGIC ( 'L' + ( 'R' << 8 ) + ( 'E' << 16 ) + ( 'T' << 24 ) )
 | 
			
		||||
 | 
			
		||||
	.text
 | 
			
		||||
	.code16
 | 
			
		||||
	.arch i386
 | 
			
		||||
@@ -15,7 +19,9 @@
 | 
			
		||||
romheader:
 | 
			
		||||
	.word	0xAA55			/* BIOS extension signature */
 | 
			
		||||
romheader_size:	.byte _load_size_sect	/* Size in 512-byte blocks */
 | 
			
		||||
	jmp	init_vector		/* Initialisation vector */
 | 
			
		||||
	jmp	init			/* Initialisation vector */
 | 
			
		||||
checksum:
 | 
			
		||||
	.byte	0
 | 
			
		||||
	.org	0x16
 | 
			
		||||
	.word	undiheader
 | 
			
		||||
	.org	0x18
 | 
			
		||||
@@ -72,7 +78,7 @@ pnpheader:
 | 
			
		||||
	.byte	0x54			/* Device indicator */
 | 
			
		||||
	.word	0x0000			/* Boot connection vector */
 | 
			
		||||
	.word	0x0000			/* Disconnect vector */
 | 
			
		||||
	.word	exec_vector		/* Boot execution vector */
 | 
			
		||||
	.word	bev_entry		/* Boot execution vector */
 | 
			
		||||
	.word	0x0000			/* Reserved */
 | 
			
		||||
	.word	0x0000			/* Static resource information vector*/
 | 
			
		||||
	.equ pnpheader_len, . - pnpheader
 | 
			
		||||
@@ -98,60 +104,180 @@ undiheader:
 | 
			
		||||
	.equ undiheader_len, . - undiheader
 | 
			
		||||
	.size undiheader, . - undiheader
 | 
			
		||||
 | 
			
		||||
/* Initialisation vector
 | 
			
		||||
/* Initialisation (called once during POST)
 | 
			
		||||
 *
 | 
			
		||||
 * Determine whether or not this is a PnP system via a signature
 | 
			
		||||
 * check.  If it is PnP, return to the PnP BIOS indicating that we are
 | 
			
		||||
 * a boot-capable device; the BIOS will call our boot execution vector
 | 
			
		||||
 * if it wants to boot us.  If it is not PnP, hook INT 19.
 | 
			
		||||
 */
 | 
			
		||||
init_vector:
 | 
			
		||||
	pushw	%si
 | 
			
		||||
	cmpw	$'$'+'P'*256, %es:0(%di)
 | 
			
		||||
	jne	notpnp
 | 
			
		||||
	cmpw	$'n'+'P'*256, %es:2(%di)
 | 
			
		||||
	jne	notpnp
 | 
			
		||||
ispnp:
 | 
			
		||||
	movw	$ispnp_message, %si
 | 
			
		||||
	jmp	99f
 | 
			
		||||
notpnp:
 | 
			
		||||
init:
 | 
			
		||||
	/* Preserve registers, clear direction flag, set %ds=%cs */
 | 
			
		||||
	pushaw
 | 
			
		||||
	pushw	%ds
 | 
			
		||||
	pushw	$0
 | 
			
		||||
	popw	%ds
 | 
			
		||||
	pushw	%es
 | 
			
		||||
	cld
 | 
			
		||||
	pushw	%cs
 | 
			
		||||
	pushw	$exec_vector
 | 
			
		||||
	popl	( 0x19 * 4 )
 | 
			
		||||
	popw	%ds
 | 
			
		||||
	movw	$notpnp_message, %si
 | 
			
		||||
99:
 | 
			
		||||
	/* Print message as early as possible */
 | 
			
		||||
	movw	$init_message, %si
 | 
			
		||||
	call	print_message
 | 
			
		||||
	movw	$0x20, %ax
 | 
			
		||||
	popw	%si
 | 
			
		||||
	lret
 | 
			
		||||
	.size init_vector, . - init_vector
 | 
			
		||||
 | 
			
		||||
ispnp_message:
 | 
			
		||||
	.asciz	"gPXE detected PnP BIOS\r\n"
 | 
			
		||||
	.size ispnp_message, . - ispnp_message
 | 
			
		||||
notpnp_message:
 | 
			
		||||
	.asciz	"gPXE detected non-PnP BIOS\r\n"
 | 
			
		||||
	.size notpnp_message, . - notpnp_message
 | 
			
		||||
 | 
			
		||||
/* Boot execution vector
 | 
			
		||||
 *pciheader_size
 | 
			
		||||
 * Called by the PnP BIOS when it wants to boot us, or via the hooked
 | 
			
		||||
 * INT 19 if we detected a non-PnP BIOS.
 | 
			
		||||
 */	
 | 
			
		||||
exec_vector:
 | 
			
		||||
	/* Obtain a reasonably-sized stack */
 | 
			
		||||
	/* Check for PnP BIOS */
 | 
			
		||||
	cmpl	$PNP_SIGNATURE, %es:0(%di)
 | 
			
		||||
	je	ispnp
 | 
			
		||||
notpnp:	/* Not PnP: hook INT19 */
 | 
			
		||||
	xorw	%ax, %ax
 | 
			
		||||
	movw	%ax, %ss
 | 
			
		||||
	movw	$0x7c00, %sp
 | 
			
		||||
	
 | 
			
		||||
	movw	%ax, %es
 | 
			
		||||
	pushw	%cs
 | 
			
		||||
	pushw	$int19_entry
 | 
			
		||||
	popl	%es:( 0x19 * 4 )
 | 
			
		||||
	jmp	99f
 | 
			
		||||
ispnp:	/* Is PnP: print PnP message */
 | 
			
		||||
	movw	$init_message_pnp, %si
 | 
			
		||||
	call	print_message
 | 
			
		||||
	/* Check for PMM */
 | 
			
		||||
	movw	$( 0xe000 - 1 ), %di
 | 
			
		||||
pmm_scan:
 | 
			
		||||
	incw	%di
 | 
			
		||||
	jz	99f
 | 
			
		||||
	movw	%di, %es
 | 
			
		||||
	cmpl	$PMM_SIGNATURE, %es:0
 | 
			
		||||
	jne	pmm_scan
 | 
			
		||||
	xorw	%bx, %bx
 | 
			
		||||
	xorw	%si, %si
 | 
			
		||||
	movzbw	%es:5, %cx
 | 
			
		||||
1:	es lodsb
 | 
			
		||||
	addb	%al, %bl
 | 
			
		||||
	loop	1b
 | 
			
		||||
	jnz	pmm_scan
 | 
			
		||||
	/* PMM found: print PMM message */
 | 
			
		||||
	movw	$init_message_pmm, %si
 | 
			
		||||
	call	print_message
 | 
			
		||||
	/* Try to allocate 2MB block via PMM */
 | 
			
		||||
	pushw	$0x0006		/* Aligned, extended memory */
 | 
			
		||||
	pushl	$0xffffffff	/* No handle */
 | 
			
		||||
	pushl	$( 0x00200000 / 16 ) /* 2MB in paragraphs */
 | 
			
		||||
	pushw	$0x0000		/* pmmAllocate */
 | 
			
		||||
	lcall	%es:*(7)
 | 
			
		||||
	addw	$12, %sp
 | 
			
		||||
	testw	%dx, %dx	/* %ax==0 even on success, since align=2MB */
 | 
			
		||||
	jnz	gotpmm
 | 
			
		||||
	movw	$init_message_pmm_failed, %si
 | 
			
		||||
	call	print_message
 | 
			
		||||
	jmp	99f
 | 
			
		||||
gotpmm:	/* PMM allocation succeeded: copy ROM to PMM block */
 | 
			
		||||
	pushal			/* PMM presence implies 1kB stack */
 | 
			
		||||
	movw	%ax, %es	/* %ax=0 already - see above */
 | 
			
		||||
	pushw	%dx
 | 
			
		||||
	pushw	%ax
 | 
			
		||||
	popl	%edi
 | 
			
		||||
	movl	%edi, image_source
 | 
			
		||||
	xorl	%esi, %esi
 | 
			
		||||
	movzbl	romheader_size, %ecx
 | 
			
		||||
	shll	$9, %ecx
 | 
			
		||||
	addr32 rep movsb	/* PMM presence implies flat real mode */
 | 
			
		||||
	movl	%edi, decompress_to
 | 
			
		||||
	/* Shrink ROM and update checksum */
 | 
			
		||||
	xorw	%bx, %bx
 | 
			
		||||
	xorw	%si, %si
 | 
			
		||||
	movb	$_prefix_size_sect, romheader_size
 | 
			
		||||
	shlw	$9, %cx
 | 
			
		||||
1:	lodsb
 | 
			
		||||
	addb	%al, %bl
 | 
			
		||||
	loop	1b
 | 
			
		||||
	subb	%bl, checksum
 | 
			
		||||
	popal
 | 
			
		||||
99:
 | 
			
		||||
	/* Print CRLF to terminate messages */
 | 
			
		||||
	movw	$init_message_crlf, %si
 | 
			
		||||
	call	print_message
 | 
			
		||||
	/* Restore registers */
 | 
			
		||||
	popw	%es
 | 
			
		||||
	popw	%ds
 | 
			
		||||
	popaw
 | 
			
		||||
	/* Indicate boot capability to PnP BIOS, if present */
 | 
			
		||||
	movw	$0x20, %ax
 | 
			
		||||
	lret
 | 
			
		||||
	.size init, . - init
 | 
			
		||||
 | 
			
		||||
init_message:
 | 
			
		||||
	.asciz	"gPXE (http://etherboot.org)"
 | 
			
		||||
	.size	init_message, . - init_message
 | 
			
		||||
init_message_pnp:
 | 
			
		||||
	.asciz	" - PnP BIOS detected"
 | 
			
		||||
	.size init_message_pnp, . - init_message_pnp
 | 
			
		||||
init_message_pmm:
 | 
			
		||||
	.asciz	", using PMM"
 | 
			
		||||
	.size init_message_pmm, . - init_message_pmm
 | 
			
		||||
init_message_pmm_failed:
 | 
			
		||||
	.asciz	" (failed)"
 | 
			
		||||
	.size init_message_pmm_failed, . - init_message_pmm_failed
 | 
			
		||||
init_message_crlf:
 | 
			
		||||
	.asciz	"\r\n"
 | 
			
		||||
	.size	init_message_crlf, . - init_message_crlf
 | 
			
		||||
 | 
			
		||||
/* ROM image location
 | 
			
		||||
 *
 | 
			
		||||
 * May be either within option ROM space, or within PMM-allocated block.
 | 
			
		||||
 */
 | 
			
		||||
image_source:
 | 
			
		||||
	.long	0
 | 
			
		||||
	.size	image_source, . - image_source
 | 
			
		||||
/* Temporary decompression area
 | 
			
		||||
 *
 | 
			
		||||
 * May be either at HIGHMEM_LOADPOINT, or within PMM-allocated block.
 | 
			
		||||
 */
 | 
			
		||||
decompress_to:
 | 
			
		||||
	.long	HIGHMEM_LOADPOINT
 | 
			
		||||
	.size	decompress_to, . - decompress_to
 | 
			
		||||
 | 
			
		||||
/* Boot Execution Vector entry point
 | 
			
		||||
 *
 | 
			
		||||
 * Called by the PnP BIOS when it wants to boot us.
 | 
			
		||||
 */
 | 
			
		||||
bev_entry:
 | 
			
		||||
	pushw	%cs
 | 
			
		||||
	call	exec
 | 
			
		||||
	lret
 | 
			
		||||
	.size	bev_entry, . - bev_entry
 | 
			
		||||
 | 
			
		||||
/* INT19 entry point
 | 
			
		||||
 *
 | 
			
		||||
 * Called via the hooked INT 19 if we detected a non-PnP BIOS.
 | 
			
		||||
 */
 | 
			
		||||
int19_entry:
 | 
			
		||||
	pushw	%cs
 | 
			
		||||
	call	exec
 | 
			
		||||
	/* No real way to return from INT19 */
 | 
			
		||||
	int	$0x18
 | 
			
		||||
	.size	int19_entry, . - int19_entry
 | 
			
		||||
 | 
			
		||||
/* Execute as a boot device
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
exec:	/* Set %ds = %cs */
 | 
			
		||||
	pushw	%cs
 | 
			
		||||
	popw	%ds
 | 
			
		||||
 | 
			
		||||
	/* Print message as soon as possible */
 | 
			
		||||
	movw	$exec_message, %si
 | 
			
		||||
	call	print_message
 | 
			
		||||
 | 
			
		||||
	call	install
 | 
			
		||||
	/* Store magic word on BIOS stack and remember BIOS %ss:sp */
 | 
			
		||||
	pushl	$STACK_MAGIC
 | 
			
		||||
	movw	%ss, %dx
 | 
			
		||||
	movw	%sp, %bp
 | 
			
		||||
 | 
			
		||||
	/* Obtain a reasonably-sized temporary stack */
 | 
			
		||||
	xorw	%ax, %ax
 | 
			
		||||
	movw	%ax, %ss
 | 
			
		||||
	movw	$0x7c00, %sp
 | 
			
		||||
 | 
			
		||||
	/* Install gPXE */
 | 
			
		||||
	movl	image_source, %esi
 | 
			
		||||
	movl	decompress_to, %edi
 | 
			
		||||
	call	alloc_basemem
 | 
			
		||||
	call	install_prealloc
 | 
			
		||||
 | 
			
		||||
	/* Set up real-mode stack */
 | 
			
		||||
	movw	%bx, %ss
 | 
			
		||||
@@ -162,13 +288,23 @@ exec_vector:
 | 
			
		||||
	pushw	$1f
 | 
			
		||||
	lret
 | 
			
		||||
	.section ".text16", "awx", @progbits
 | 
			
		||||
1:
 | 
			
		||||
1:	/* Call main() */
 | 
			
		||||
	pushl	$main
 | 
			
		||||
	pushw	%cs
 | 
			
		||||
	call	prot_call
 | 
			
		||||
	popl	%eax /* discard */
 | 
			
		||||
	/* No need to clean up stack; we are about to reload %ss:sp */
 | 
			
		||||
	
 | 
			
		||||
	/* Restore BIOS stack */
 | 
			
		||||
	movw	%dx, %ss
 | 
			
		||||
	movw	%bp, %sp
 | 
			
		||||
 | 
			
		||||
	/* Boot next device */
 | 
			
		||||
	/* Check magic word on BIOS stack */
 | 
			
		||||
	popl	%eax
 | 
			
		||||
	cmpl	$STACK_MAGIC, %eax
 | 
			
		||||
	jne	1f
 | 
			
		||||
	/* BIOS stack OK: return to caller */
 | 
			
		||||
	lret
 | 
			
		||||
1:	/* BIOS stack corrupt: use INT 18 */
 | 
			
		||||
	int	$0x18
 | 
			
		||||
	.previous
 | 
			
		||||
 | 
			
		||||
@@ -182,6 +318,7 @@ exec_message:
 | 
			
		||||
 */
 | 
			
		||||
undiloader:
 | 
			
		||||
	/* Save registers */
 | 
			
		||||
	pushl	%esi
 | 
			
		||||
	pushl	%edi
 | 
			
		||||
	pushw	%es
 | 
			
		||||
	pushw	%bx
 | 
			
		||||
@@ -193,6 +330,8 @@ undiloader:
 | 
			
		||||
	pushw	%di
 | 
			
		||||
	movw	%es:12(%di), %bx
 | 
			
		||||
	movw	%es:14(%di), %ax
 | 
			
		||||
	movl	%cs:image_source, %esi
 | 
			
		||||
	movl	%cs:decompress_to, %edi
 | 
			
		||||
	call	install_prealloc
 | 
			
		||||
	popw	%di
 | 
			
		||||
	/* Call UNDI loader C code */
 | 
			
		||||
@@ -208,6 +347,7 @@ undiloader:
 | 
			
		||||
	popw	%bx
 | 
			
		||||
	popw	%es
 | 
			
		||||
	popl	%edi
 | 
			
		||||
	popl	%esi
 | 
			
		||||
	lret
 | 
			
		||||
	.size undiloader, . - undiloader
 | 
			
		||||
				
 | 
			
		||||
@@ -218,7 +358,7 @@ print_message:
 | 
			
		||||
	pushw	%bx
 | 
			
		||||
	pushw	%bp
 | 
			
		||||
	movw    $0x0007, %bx
 | 
			
		||||
1:	cs lodsb
 | 
			
		||||
1:	lodsb
 | 
			
		||||
	testb	%al, %al
 | 
			
		||||
	je	2f
 | 
			
		||||
	movb    $0x0e, %ah              /* write char, tty mode */
 | 
			
		||||
 
 | 
			
		||||
@@ -257,6 +257,8 @@ SECTIONS {
 | 
			
		||||
    /*
 | 
			
		||||
     * Values calculated to save code from doing it
 | 
			
		||||
     */
 | 
			
		||||
    _prefix_size_pgh	= ( ( _prefix_size + 15 ) / 16 );
 | 
			
		||||
    _prefix_size_sect	= ( ( _prefix_size + 511 ) / 512 );
 | 
			
		||||
    _text16_size_pgh	= ( ( _text16_size + 15 ) / 16 );
 | 
			
		||||
    _data16_size_pgh	= ( ( _data16_size + 15 ) / 16 );
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user