diff options
author | Michael Brown <mcb30@ipxe.org> | 2012-06-10 18:25:26 +0100 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2012-06-12 15:15:03 +0100 |
commit | 9e8d431a0d58caba3c5f65d4e30fd259d2f782e1 (patch) | |
tree | 357391dd1bbd9b6f0d98dd099aafec60f9bdf80e /src/arch | |
parent | 12be8bc544b25fbed1fa5ef6c89cad42aaa268ea (diff) | |
download | ipxe-9e8d431a0d58caba3c5f65d4e30fd259d2f782e1.zip ipxe-9e8d431a0d58caba3c5f65d4e30fd259d2f782e1.tar.gz ipxe-9e8d431a0d58caba3c5f65d4e30fd259d2f782e1.tar.bz2 |
[romprefix] Add a dummy ROM header to cover the .mrom payload
The header of a .mrom image declares its length to be only a few
kilobytes; the remainder is accessed via a sideband mechanism. This
makes it difficult to append an additional ROM image, such as an EFI
ROM.
Add a second, dummy ROM header covering the payload portion of the
.mrom image, allowing consumers to locate any appended ROM images in
the usual way.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/arch')
-rw-r--r-- | src/arch/i386/prefix/libprefix.S | 26 | ||||
-rw-r--r-- | src/arch/i386/prefix/mromprefix.S | 103 | ||||
-rw-r--r-- | src/arch/i386/prefix/romprefix.S | 46 | ||||
-rw-r--r-- | src/arch/i386/scripts/i386.lds | 25 |
4 files changed, 135 insertions, 65 deletions
diff --git a/src/arch/i386/prefix/libprefix.S b/src/arch/i386/prefix/libprefix.S index 0962deb..e5bc7bb 100644 --- a/src/arch/i386/prefix/libprefix.S +++ b/src/arch/i386/prefix/libprefix.S @@ -663,18 +663,22 @@ install_prealloc: /* Save decompression temporary area physical address */ pushl %edi - /* Install .text16.early */ + /* Install .text16.early and calculate %ecx as offset to next block */ progress " .text16.early\n" pushl %esi xorl %esi, %esi movw %cs, %si shll $4, %esi + pushl %esi /* Save original %cs:0000 */ addl $_text16_early_lma, %esi movzwl %ax, %edi shll $4, %edi movl $_text16_early_filesz, %ecx movl $_text16_early_memsz, %edx call install_block /* .text16.early */ + popl %ecx /* Calculate offset to next block */ + subl %esi, %ecx + negl %ecx popl %esi #ifndef KEEP_IT_REAL @@ -729,7 +733,7 @@ payload_death_message: jnz 1f movw %cs, %si shll $4, %esi -1: addl payload_lma, %esi +1: addl %ecx, %esi /* Install .text16.late and .data16 */ progress " .text16.late\n" @@ -850,17 +854,6 @@ close_payload_vector: .word 0 .size close_payload_vector, . - close_payload_vector - /* Payload address */ - .section ".prefix.lib", "awx", @progbits -payload_lma: - .long 0 - .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */ - .ascii "ADHL" - .long payload_lma - .long 1 - .long 0 - .previous - /* Dummy routines to open and close payload */ .section ".text16.early.data", "aw", @progbits .weak open_payload @@ -914,6 +907,10 @@ uninstall: .ascii "PAYL" .long 0 .long 0 + .long _payload_align + .ascii "COPY" + .long _pprefix_lma + .long _pprefix_filesz .long _max_align .ascii PACK_OR_COPY .long _text16_late_lma @@ -927,3 +924,6 @@ uninstall: .long _textdata_lma .long _textdata_filesz .long _max_align + + .weak _payload_align + .equ _payload_align, 1 diff --git a/src/arch/i386/prefix/mromprefix.S b/src/arch/i386/prefix/mromprefix.S index 7bbe44c..d7b7fc3 100644 --- a/src/arch/i386/prefix/mromprefix.S +++ b/src/arch/i386/prefix/mromprefix.S @@ -30,6 +30,7 @@ FILE_LICENCE ( GPL2_OR_LATER ) #define PCI_BAR_EXPROM 0x30 #define ROMPREFIX_EXCLUDE_PAYLOAD 1 +#define ROMPREFIX_MORE_IMAGES 1 #define _rom_start _mrom_start #include "romprefix.S" @@ -46,8 +47,10 @@ FILE_LICENCE ( GPL2_OR_LATER ) * Parameters: * %ds:0000 : Prefix * %esi : Buffer for copy of image source (or zero if no buffer available) + * %ecx : Expected offset within buffer of first payload block * Returns: * %esi : Valid image source address (buffered or unbuffered) + * %ecx : Actual offset within buffer of first payload block * CF set on error */ .section ".text16.early", "awx", @progbits @@ -56,23 +59,25 @@ open_payload: /* Preserve registers */ pushl %eax pushw %bx - pushl %ecx pushl %edx pushl %edi pushw %bp + pushw %es pushw %ds - /* Retrieve bus:dev.fn and image source length from .prefix */ + /* Retrieve bus:dev.fn from .prefix */ movw init_pci_busdevfn, %bx - movl image_source_len_dword, %ecx /* Set up %ds for access to .text16.early */ pushw %cs popw %ds - /* Store bus:dev.fn and image source length to .text16.early */ + /* Set up %es for access to flat address space */ + xorw %ax, %ax + movw %ax, %es + + /* Store bus:dev.fn to .text16.early */ movw %bx, payload_pci_busdevfn - movl %ecx, rom_bar_copy_len_dword /* Get expansion ROM BAR current value */ movw $PCI_BAR_EXPROM, %di @@ -159,27 +164,32 @@ find_mem_bar: * properly support flat real mode, it will die horribly.) */ pushl %esi - pushw %es movl %esi, %edi movl %eax, %esi - movl rom_bar_copy_len_dword, %ecx - xorw %ax, %ax - movw %ax, %es + addr32 es movzbl 2(%esi), %ecx + shll $7, %ecx + addr32 es movzbl 2(%esi,%ecx,4), %edx + shll $7, %edx + addl %edx, %ecx addr32 es rep movsl - popw %es popl %esi jmp 2f 1: /* We have no buffer; set %esi to the BAR address */ movl %eax, %esi 2: + /* Locate first payload block (after the dummy ROM header) */ + addr32 es movzbl 2(%esi), %ecx + shll $9, %ecx + addl $_pprefix_skip, %ecx + clc /* Restore registers and return */ 99: popw %ds + popw %es popw %bp popl %edi popl %edx - popl %ecx popw %bx popl %eax lret @@ -201,11 +211,6 @@ rom_bar_size: .size rom_bar_size, . - rom_bar_size .section ".text16.early.data", "aw", @progbits -rom_bar_copy_len_dword: - .long 0 - .size rom_bar_copy_len_dword, . - rom_bar_copy_len_dword - - .section ".text16.early.data", "aw", @progbits stolen_bar_register: .word 0 .size stolen_bar_register, . - stolen_bar_register @@ -419,16 +424,68 @@ pci_set_mem_access: ret .size pci_set_mem_access, . - pci_set_mem_access -/* Image source area length (in dwords) +/* Payload prefix * + * We include a dummy ROM header to cover the "hidden" portion of the + * overall ROM image. */ - .section ".prefix", "ax", @progbits -image_source_len_dword: + .globl _payload_align + .equ _payload_align, 512 + .section ".pprefix", "ax", @progbits + .org 0x00 +mromheader: + .word 0xaa55 /* BIOS extension signature */ +mromheader_size: .byte 0 /* Size in 512-byte blocks */ + .org 0x18 + .word mpciheader + .org 0x1a + .word 0 + .size mromheader, . - mromheader + + .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */ + .ascii "APPB" + .long mromheader_size + .long 512 + .long 0 + .previous + +mpciheader: + .ascii "PCIR" /* Signature */ + .word pci_vendor_id /* Vendor identification */ + .word pci_device_id /* Device identification */ + .word 0x0000 /* Device list pointer */ + .word mpciheader_len /* PCI data structure length */ + .byte 0x03 /* PCI data structure revision */ + .byte 0x02, 0x00, 0x00 /* Class code */ +mpciheader_image_length: + .word 0 /* Image length */ + .word 0x0001 /* Revision level */ + .byte 0xff /* Code type */ + .byte 0x80 /* Last image indicator */ +mpciheader_runtime_length: + .word 0 /* Maximum run-time image length */ + .word 0x0000 /* Configuration utility code header */ + .word 0x0000 /* DMTF CLP entry point */ + .equ mpciheader_len, . - mpciheader + .size mpciheader, . - mpciheader + + .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */ + .ascii "APPW" + .long mpciheader_image_length + .long 512 .long 0 - .size image_source_len_dword, . - image_source_len_dword + .ascii "APPW" + .long mpciheader_runtime_length + .long 512 + .long 0 + .previous + +/* Fix up additional image source size + * + */ .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */ - .ascii "ADDL" - .long image_source_len_dword - .long 4 + .ascii "ADPW" + .long extra_size + .long 512 .long 0 .previous diff --git a/src/arch/i386/prefix/romprefix.S b/src/arch/i386/prefix/romprefix.S index 0f92415..950e084 100644 --- a/src/arch/i386/prefix/romprefix.S +++ b/src/arch/i386/prefix/romprefix.S @@ -41,6 +41,14 @@ FILE_LICENCE ( GPL2_OR_LATER ) #define ZINFO_TYPE_ADxW "ADDW" #endif +/* Allow ROM to be marked as containing multiple images + */ +#if ROMPREFIX_MORE_IMAGES +#define INDICATOR 0x00 +#else +#define INDICATOR 0x80 +#endif + .text .code16 .arch i386 @@ -85,7 +93,7 @@ pciheader_image_length: .word 0 /* Image length */ .word 0x0001 /* Revision level */ .byte 0x00 /* Code type */ - .byte 0x80 /* Last image indicator */ + .byte INDICATOR /* Last image indicator */ pciheader_runtime_length: .word 0 /* Maximum run-time image length */ .word 0x0000 /* Configuration utility code header */ @@ -98,7 +106,7 @@ pciheader_runtime_length: .long pciheader_image_length .long 512 .long 0 - .ascii ZINFO_TYPE_ADxW + .ascii "ADHW" .long pciheader_runtime_length .long 512 .long 0 @@ -327,7 +335,8 @@ pmm_scan: /* We have PMM and so a 1kB stack: preserve whole registers */ pushal /* Allocate image source PMM block */ - movzwl image_source_size, %ecx + movzbl romheader_size, %ecx + addw extra_size, %cx shll $5, %ecx movl $PMM_HANDLE_BASE_IMAGE_SOURCE, %ebx movw $get_pmm_image_source, %bp @@ -341,11 +350,11 @@ pmm_scan: movl %esi, %edi xorl %esi, %esi movzbl romheader_size, %ecx - shll $9, %ecx - addr32 rep movsb /* PMM presence implies flat real mode */ + shll $7, %ecx + addr32 rep movsl /* PMM presence implies flat real mode */ popw %es /* Shrink ROM */ - movb shrunk_rom_size, %al + movw pciheader_runtime_length, %ax movb %al, romheader_size 1: /* Allocate decompression PMM block. Round up the size to the * nearest 128kB and use the size within the PMM handle; this @@ -573,31 +582,12 @@ image_source: .long 0 .size image_source, . - image_source -/* Image source size (in 512-byte sectors) +/* Additional image source size (in 512-byte sectors) * */ -image_source_size: +extra_size: .word 0 - .size image_source_size, . - image_source_size - .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */ - .ascii "ADDW" - .long image_source_size - .long 512 - .long 0 - .previous - -/* Shrunk ROM size (in 512-byte sectors) - * - */ -shrunk_rom_size: - .byte 0 - .size shrunk_rom_size, . - shrunk_rom_size - .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */ - .ascii "ADHB" - .long shrunk_rom_size - .long 512 - .long 0 - .previous + .size extra_size, . - extra_size /* Temporary decompression area * diff --git a/src/arch/i386/scripts/i386.lds b/src/arch/i386/scripts/i386.lds index 763b80d..fb76365 100644 --- a/src/arch/i386/scripts/i386.lds +++ b/src/arch/i386/scripts/i386.lds @@ -1,4 +1,4 @@ -/* -*- sh -*- */ +/* -*- ld-script -*- */ /* * Linker script for i386 images @@ -122,6 +122,23 @@ SECTIONS { _textdata_memsz = ABSOLUTE ( _etextdata ) - ABSOLUTE ( _textdata ); /* + * Payload prefix + * + * If present, this will be placed between .text16.early and .text16.late. + * + */ + .pprefix 0x0 : AT ( _pprefix_lma ) { + _pprefix = .; + KEEP(*(.pprefix)) + KEEP(*(.pprefix.*)) + _mpprefix = .; + } .bss.pprefix (NOLOAD) : AT ( _end_lma ) { + _epprefix = .; + } + _pprefix_filesz = ABSOLUTE ( _mpprefix ) - ABSOLUTE ( _pprefix ); + _pprefix_memsz = ABSOLUTE ( _epprefix ) - ABSOLUTE ( _pprefix ); + + /* * Compressor information block * */ @@ -188,7 +205,13 @@ SECTIONS { . += _text16_early_filesz; . = ALIGN ( _max_align ); + . = ALIGN ( _payload_align ); + _pprefix_lma = .; + . += _pprefix_filesz; + + . = ALIGN ( _max_align ); _payload_lma = .; + _pprefix_skip = ABSOLUTE ( _payload_lma ) - ABSOLUTE ( _pprefix_lma ); _text16_late_lma = .; . += _text16_late_filesz; |