Skip to content

Commit

Permalink
[romprefix] Add .mrom format, allowing loading of large ROMs
Browse files Browse the repository at this point in the history
Add an infrastructure allowing the prefix to provide an open_payload()
method for obtaining out-of-band access to the whole iPXE image.  Add
a mechanism within this infrastructure that allows raw access to the
expansion ROM BAR by temporarily borrowing an address from a suitable
memory BAR on the same PCI card.

For cards that have a memory BAR that is at least as large as their
expansion ROM BAR, this allows large iPXE ROMs to be supported even on
systems where PMM fails, or where option ROM space pressure makes it
impossible to use PMM shrinking.  The BIOS sees only a stub ROM of
approximately 3kB in size; the remainder (which can be well over 64kB)
is loaded only at the time iPXE is invoked.

As a nice side-effect, an iPXE .mrom image will continue to work even
if its PMM-allocated areas are overwritten between initialisation and
invocation.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
  • Loading branch information
mcb30 committed Apr 25, 2010
1 parent d8c1f2e commit 132c391
Show file tree
Hide file tree
Showing 5 changed files with 518 additions and 9 deletions.
3 changes: 3 additions & 0 deletions src/arch/i386/Makefile.pcbios
Expand Up @@ -11,6 +11,7 @@ LDFLAGS += -N --no-check-sections
# Media types.
#
MEDIA += rom
MEDIA += mrom
MEDIA += pxe
MEDIA += kpxe
MEDIA += kkpxe
Expand All @@ -23,12 +24,14 @@ MEDIA += raw
# Padding rules
#
PAD_rom = $(PADIMG) --blksize=512 --byte=0xff $@
PAD_mrom = $(PAD_rom)
PAD_dsk = $(PADIMG) --blksize=512 $@
PAD_hd = $(PADIMG) --blksize=32768 $@

# Finalisation rules
#
FINALISE_rom = $(FIXROM) $@
FINALISE_mrom = $(FINALISE_rom)

# rule to make a non-emulation ISO boot image
NON_AUTO_MEDIA += iso
Expand Down
51 changes: 48 additions & 3 deletions src/arch/i386/prefix/libprefix.S
Expand Up @@ -479,6 +479,10 @@ install_prealloc:
cld /* Sanity: clear the direction flag asap */
pushfw

/* Set up %ds for (read-only) access to .prefix */
pushw %cs
popw %ds

/* Copy decompression temporary area physical address to %ebp */
movl %edi, %ebp

Expand All @@ -495,7 +499,6 @@ install_prealloc:
call install_block /* .text16.early */
popl %esi

/* Open up access to payload */
#ifndef KEEP_IT_REAL
/* Access high memory */
pushw %cs
Expand All @@ -511,18 +514,39 @@ install_prealloc:
2: jmp 2b
.section ".prefix.data", "aw", @progbits
a20_death_message:
.asciz "Gate A20 stuck - cannot continue\n"
.asciz "\nHigh memory inaccessible - cannot continue\n"
.size a20_death_message, . - a20_death_message
.previous
3:
#endif

/* Open payload (which may not yet be in memory) */
pushw %cs
pushw $1f
pushw %ax
pushw $open_payload
lret
1: /* Die if we could not access the payload */
jnc 3f
xorw %di, %di
movl %esi, %eax
call print_hex_dword
movw $payload_death_message, %si
call print_message
2: jmp 2b
.section ".prefix.data", "aw", @progbits
payload_death_message:
.asciz "\nPayload inaccessible - cannot continue\n"
.size payload_death_message, . - payload_death_message
.previous
3:

/* Calculate physical address of payload (i.e. first source) */
testl %esi, %esi
jnz 1f
movw %cs, %si
shll $4, %esi
1: addl %cs:payload_lma, %esi
1: addl payload_lma, %esi

/* Install .text16.late and .data16 */
movl $_text16_late_filesz, %ecx
Expand Down Expand Up @@ -588,16 +612,22 @@ a20_death_message:

/* Copy code to new location */
pushl %edi
pushw %ax
xorw %ax, %ax
movw %ax, %es
es rep addr32 movsb
popw %ax
popl %edi

/* Initialise librm at new location */
lcall *init_librm_vector
skip_relocate:
#endif

/* Close access to payload */
movw %ax, (close_payload_vector+2)
lcall *close_payload_vector

/* Restore registers */
popfw
popw %es
Expand Down Expand Up @@ -625,6 +655,10 @@ prot_call_vector:
.word 0
.size prot_call_vector, . - prot_call_vector
#endif
close_payload_vector:
.word close_payload
.word 0
.size close_payload_vector, . - close_payload_vector

/* Payload address */
.section ".prefix.lib", "awx", @progbits
Expand All @@ -637,6 +671,17 @@ payload_lma:
.long 0
.previous

/* Dummy routines to open and close payload */
.section ".text16.early.data", "aw", @progbits
.weak open_payload
.weak close_payload
open_payload:
close_payload:
clc
lret
.size open_payload, . - open_payload
.size close_payload, . - close_payload

/****************************************************************************
* uninstall
*
Expand Down

0 comments on commit 132c391

Please sign in to comment.