*/
__asmcall void relocate ( struct i386_all_regs *ix86 ) {
struct memory_map memmap;
- unsigned long start, end, size, padded_size;
+ unsigned long start, end, size, padded_size, max;
unsigned long new_start, new_end;
unsigned i;
"...need %lx bytes for %d-byte alignment\n",
start, end, padded_size, max_align );
+ /* Determine maximum usable address */
+ max = MAX_ADDR;
+ if ( ix86->regs.ebp && ( ix86->regs.ebp < max ) ) {
+ max = ix86->regs.ebp;
+ DBG ( "Limiting relocation to [0,%lx)\n", max );
+ }
+
/* Walk through the memory map and find the highest address
* below 4GB that iPXE will fit into.
*/
DBG ( "Considering [%llx,%llx)\n", region->start, region->end);
- /* Truncate block to MAX_ADDR. This will be less than
- * 4GB, which means that we can get away with using
- * just 32-bit arithmetic after this stage.
+ /* Truncate block to maximum address. This will be
+ * less than 4GB, which means that we can get away
+ * with using just 32-bit arithmetic after this stage.
*/
- if ( region->start > MAX_ADDR ) {
- DBG ( "...starts after MAX_ADDR=%lx\n", MAX_ADDR );
+ if ( region->start > max ) {
+ DBG ( "...starts after max=%lx\n", max );
continue;
}
r_start = region->start;
- if ( region->end > MAX_ADDR ) {
- DBG ( "...end truncated to MAX_ADDR=%lx\n", MAX_ADDR );
- r_end = MAX_ADDR;
+ if ( region->end > max ) {
+ DBG ( "...end truncated to max=%lx\n", max );
+ r_end = max;
} else {
r_end = region->end;
}
call alloc_basemem
xorl %esi, %esi
movl $EXE_DECOMPRESS_ADDRESS, %edi
- clc
+ xorl %ebp, %ebp
call install_prealloc
/* Set up real-mode stack */
#ifndef KEEP_IT_REAL
/* Preserve registers */
- pushfw
pushl %eax
pushl %ebp
/* Restore registers and return */
popl %ebp
popl %eax
- popfw
ret
#else /* KEEP_IT_REAL */
/* Preserve registers */
pushl %esi
pushl %edi
+ pushl %ebp
/* Allocate space for .text16 and .data16 */
call alloc_basemem
/* Image source = %cs:0000 */
xorl %esi, %esi
/* Image destination = default */
xorl %edi, %edi
- /* Allow relocation */
- clc
+ /* Allow arbitrary relocation */
+ xorl %ebp, %ebp
/* Install text and data segments */
call install_prealloc
/* Restore registers and return */
+ popl %ebp
popl %edi
popl %esi
ret
* %bx : .data16 segment address
* %esi : Image source physical address (or zero for %cs:0000)
* %edi : Decompression temporary area physical address (or zero for default)
- * CF set : Avoid relocating to top of memory
+ * %ebp : Maximum end address for relocation (or zero for no maximum)
* Corrupts:
* none
****************************************************************************
pushw %ds
pushw %es
cld /* Sanity: clear the direction flag asap */
- pushfw
/* Set up %ds for (read-only) access to .prefix */
pushw %cs
movw %ax, (init_librm_vector+2)
lcall *init_librm_vector
- /* Skip relocation if CF was set on entry */
- popfw
- pushfw
- jc skip_relocate
-
/* Call relocate() to determine target address for relocation.
* relocate() will return with %esi, %edi and %ecx set up
* ready for the copy to the new location.
/* Initialise librm at new location */
progress " init_librm\n"
lcall *init_librm_vector
-skip_relocate:
#endif
/* Close access to payload */
lcall *close_payload_vector
/* Restore registers */
- popfw
popw %es
popw %ds
popal
* picked up by the initial shell prompt, and we will drop
* into a shell.
*/
- stc /* Inhibit relocation */
+ movl $0xa0000, %ebp /* Inhibit relocation during POST */
pushw %cs
call exec
2:
* Called by the PnP BIOS when it wants to boot us.
*/
bev_entry:
- clc /* Allow relocation */
+ xorl %ebp, %ebp /* Allow relocation */
pushw %cs
call exec
lret
/* Leave keypress in buffer and start iPXE. The keypress will
* cause the usual initial Ctrl-B prompt to be skipped.
*/
- clc /* Allow relocation */
+ xorl %ebp, %ebp /* Allow relocation */
pushw %cs
call exec
1: /* Try to call original INT 19 vector */
pushw %cs
popw %ds
- /* Preserve state of CF */
- lahf
-
/* Print message as soon as possible */
movw $prodstr, %si
xorw %di, %di
/* Store magic word on BIOS stack and remember BIOS %ss:sp */
pushl $STACK_MAGIC
- movw %ss, %dx
- movw %sp, %bp
+ movw %ss, %cx
+ movw %sp, %dx
/* Obtain a reasonably-sized temporary stack */
xorw %bx, %bx
movw $0x7c00, %sp
/* Install iPXE */
- sahf
- pushfw
call alloc_basemem
- popfw
movl image_source, %esi
movl decompress_to, %edi
call install_prealloc
pushl $main
pushw %cs
call prot_call
- popl %ecx /* discard */
+ popl %eax /* discard */
/* Uninstall iPXE */
call uninstall
/* Restore BIOS stack */
- movw %dx, %ss
- movw %bp, %sp
+ movw %cx, %ss
+ movw %dx, %sp
/* Check magic word on BIOS stack */
popl %eax
/* Save registers */
pushl %esi
pushl %edi
+ pushl %ebp
pushw %ds
pushw %es
pushw %bx
movw %es:14(%di), %ax
movl image_source, %esi
movl decompress_to, %edi
- clc /* Allow relocation */
+ xorl %ebp, %ebp /* Allow relocation */
call install_prealloc
popw %di
/* Call UNDI loader C code */
popw %bx
popw %es
popw %ds
+ popl %ebp
popl %edi
popl %esi
lret