david/ipxe
Archived
1
0

[prefix] Add .text16.early section

Add a section .text16.early which is always kept inline with the
prefix.  This will allow for some code sharing between the .prefix and
.text16 sections.

Note that the simple solution of just prepending the .prefix section
to the .text16 section will not work, because a bug in Wyse Streaming
Manager server (WLDRM13.BIN) requires us to place a dummy PXENV+ entry
point at the start of .text16.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown 2010-04-20 11:05:53 +01:00
parent 6c35a525da
commit 9068249e24
4 changed files with 150 additions and 39 deletions

View File

@ -406,6 +406,7 @@ copy_bytes:
* %edx : total length of block (including any uninitialised data portion) * %edx : total length of block (including any uninitialised data portion)
* Returns: * Returns:
* %esi : next source physical address (will be a multiple of 16) * %esi : next source physical address (will be a multiple of 16)
* %edi : next destination physical address (will be a multiple of 16)
* Corrupts: * Corrupts:
* none * none
**************************************************************************** ****************************************************************************
@ -417,7 +418,6 @@ install_block:
pushw %ds pushw %ds
pushw %es pushw %es
pushl %ecx pushl %ecx
pushl %edi
/* Convert %esi and %edi to %ds:esi and %es:edi */ /* Convert %esi and %edi to %ds:esi and %es:edi */
shrl $4, %esi shrl $4, %esi
@ -445,18 +445,23 @@ install_block:
rep addr32 stosb rep addr32 stosb
popw %ax popw %ax
/* Round up %esi to start of next source block */ /* Round up %esi and %edi to start of next blocks */
addl $0xf, %esi addl $0xf, %esi
andl $~0xf, %esi andl $~0xf, %esi
addl $0xf, %edi
andl $~0xf, %edi
/* Convert %ds:esi back to a physical address */ /* Convert %ds:esi and %es:edi back to physical addresses */
xorl %ecx, %ecx xorl %ecx, %ecx
movw %ds, %cx movw %ds, %cx
shll $4, %ecx shll $4, %ecx
addl %ecx, %esi addl %ecx, %esi
xorl %ecx, %ecx
movw %es, %cx
shll $4, %ecx
addl %ecx, %edi
/* Restore registers and return */ /* Restore registers and return */
popl %edi
popl %ecx popl %ecx
popw %es popw %es
popw %ds popw %ds
@ -626,6 +631,23 @@ install_prealloc:
/* Sanity: clear the direction flag asap */ /* Sanity: clear the direction flag asap */
cld cld
/* Copy decompression temporary area physical address to %ebp */
movl %edi, %ebp
/* Install .text16.early */
pushl %esi
xorl %esi, %esi
movw %cs, %si
shll $4, %esi
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 %esi
/* Open up access to payload */
#ifndef KEEP_IT_REAL #ifndef KEEP_IT_REAL
/* Flatten real mode */ /* Flatten real mode */
call flatten_real_mode call flatten_real_mode
@ -636,21 +658,17 @@ install_prealloc:
jnz 1f jnz 1f
movw %cs, %si movw %cs, %si
shll $4, %esi shll $4, %esi
1: addl $_payload_lma, %esi 1: addl %cs:payload_lma, %esi
/* Install .text16 and .data16 */ /* Install .text16.late and .data16 */
pushl %edi movl $_text16_late_filesz, %ecx
movzwl %ax, %edi movl $_text16_late_memsz, %edx
shll $4, %edi call install_block /* .text16.late */
movl $_text16_memsz, %ecx
movl %ecx, %edx
call install_block /* .text16 */
movzwl %bx, %edi movzwl %bx, %edi
shll $4, %edi shll $4, %edi
movl $_data16_filesz, %ecx movl $_data16_filesz, %ecx
movl $_data16_memsz, %edx movl $_data16_memsz, %edx
call install_block /* .data16 */ call install_block /* .data16 */
popl %edi
/* Set up %ds for access to .data16 */ /* Set up %ds for access to .data16 */
movw %bx, %ds movw %bx, %ds
@ -664,12 +682,14 @@ install_prealloc:
* prior to reading the E820 memory map and relocating * prior to reading the E820 memory map and relocating
* properly. * properly.
*/ */
movl %ebp, %edi
movl $_textdata_filesz, %ecx movl $_textdata_filesz, %ecx
movl $_textdata_memsz, %edx movl $_textdata_memsz, %edx
call install_block call install_block
/* Initialise librm at current location */ /* Initialise librm at current location */
movw %ax, (init_librm_vector+2) movw %ax, (init_librm_vector+2)
movl %ebp, %edi
lcall *init_librm_vector lcall *init_librm_vector
/* Call relocate() to determine target address for relocation. /* Call relocate() to determine target address for relocation.
@ -682,13 +702,13 @@ install_prealloc:
popl %edx /* discard */ popl %edx /* discard */
/* Copy code to new location */ /* Copy code to new location */
pushl %edi
xorw %ax, %ax xorw %ax, %ax
movw %ax, %es movw %ax, %es
movl %ebp, %edi
es rep addr32 movsb es rep addr32 movsb
popl %edi
/* Initialise librm at new location */ /* Initialise librm at new location */
movl %ebp, %edi
lcall *init_librm_vector lcall *init_librm_vector
#endif #endif
@ -719,6 +739,17 @@ prot_call_vector:
.size prot_call_vector, . - prot_call_vector .size prot_call_vector, . - prot_call_vector
#endif #endif
/* 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
/**************************************************************************** /****************************************************************************
* uninstall * uninstall
* *
@ -745,27 +776,32 @@ uninstall:
/* File split information for the compressor */ /* File split information for the compressor */
#if COMPRESS #if COMPRESS
#define PACK_OR_COPY "PACK"
#else
#define PACK_OR_COPY "COPY"
#endif
.section ".zinfo", "a", @progbits .section ".zinfo", "a", @progbits
.ascii "COPY" .ascii "COPY"
.long _prefix_lma .long _prefix_lma
.long _prefix_filesz .long _prefix_filesz
.long _max_align .long _max_align
.ascii "PACK" .ascii PACK_OR_COPY
.long _text16_lma .long _text16_early_lma
.long _text16_filesz .long _text16_early_filesz
.long _max_align .long _max_align
.ascii "PACK" .ascii "PAYL"
.long 0
.long 0
.long _max_align
.ascii PACK_OR_COPY
.long _text16_late_lma
.long _text16_late_filesz
.long _max_align
.ascii PACK_OR_COPY
.long _data16_lma .long _data16_lma
.long _data16_filesz .long _data16_filesz
.long _max_align .long _max_align
.ascii "PACK" .ascii PACK_OR_COPY
.long _textdata_lma .long _textdata_lma
.long _textdata_filesz .long _textdata_filesz
.long _max_align .long _max_align
#else /* COMPRESS */
.section ".zinfo", "a", @progbits
.ascii "COPY"
.long _prefix_lma
.long _filesz
.long _max_align
#endif /* COMPRESS */

View File

@ -362,7 +362,8 @@ got_pmm: /* PMM allocation succeeded */
addr32 rep movsb /* PMM presence implies flat real mode */ addr32 rep movsb /* PMM presence implies flat real mode */
movl %edi, decompress_to movl %edi, decompress_to
/* Shrink ROM */ /* Shrink ROM */
movb $_prefix_memsz_sect, romheader_size movb shrunk_rom_size, %al
movb %al, romheader_size
pmm_fail: pmm_fail:
/* Restore upper register halves */ /* Restore upper register halves */
popal popal
@ -488,6 +489,19 @@ image_source:
.long 0 .long 0
.size image_source, . - image_source .size image_source, . - image_source
/* 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
/* Temporary decompression area /* Temporary decompression area
* *
* May be either at HIGHMEM_LOADPOINT, or within PMM-allocated block. * May be either at HIGHMEM_LOADPOINT, or within PMM-allocated block.

View File

@ -45,17 +45,25 @@ SECTIONS {
* *
*/ */
.text16 0x0 : AT ( _text16_lma ) { .text16.early 0x0 : AT ( _text16_early_lma ) {
_text16 = .; _text16 = .;
*(.text16.null) *(.text16.null)
. += 1; /* Prevent NULL being valid */ . += 1; /* Prevent NULL being valid */
*(.text16.early)
*(.text16.early.*)
_etext16_early = .;
} .text16.late ALIGN ( _max_align ) : AT ( _text16_late_lma ) {
_text16_late = .;
*(.text16) *(.text16)
*(.text16.*) *(.text16.*)
_mtext16 = .; _mtext16 = .;
} .bss.text16 (NOLOAD) : AT ( _end_lma ) { } .bss.text16 (NOLOAD) : AT ( _end_lma ) {
_etext16 = .; _etext16 = .;
} }
_text16_filesz = ABSOLUTE ( _mtext16 - _text16 ); _text16_early_filesz = ABSOLUTE ( _etext16_early - _text16 );
_text16_early_memsz = ABSOLUTE ( _etext16_early - _text16 );
_text16_late_filesz = ABSOLUTE ( _mtext16 - _text16_late );
_text16_late_memsz = ABSOLUTE ( _etext16 - _text16_late );
_text16_memsz = ABSOLUTE ( _etext16 - _text16 ); _text16_memsz = ABSOLUTE ( _etext16 - _text16 );
/* /*
@ -168,10 +176,14 @@ SECTIONS {
_prefix_lma = .; _prefix_lma = .;
. += _prefix_filesz; . += _prefix_filesz;
. = ALIGN ( _max_align );
_text16_early_lma = .;
. += _text16_early_filesz;
. = ALIGN ( _max_align ); . = ALIGN ( _max_align );
_payload_lma = .; _payload_lma = .;
_text16_lma = .; _text16_late_lma = .;
. += _text16_filesz; . += _text16_late_filesz;
. = ALIGN ( _max_align ); . = ALIGN ( _max_align );
_data16_lma = .; _data16_lma = .;
@ -194,8 +206,6 @@ SECTIONS {
* Values calculated to save code from doing it * Values calculated to save code from doing it
* *
*/ */
_prefix_memsz_pgh = ( ( _prefix_memsz + 15 ) / 16 );
_prefix_memsz_sect = ( ( _prefix_memsz + 511 ) / 512 );
_text16_memsz_pgh = ( ( _text16_memsz + 15 ) / 16 ); _text16_memsz_pgh = ( ( _text16_memsz + 15 ) / 16 );
_data16_memsz_pgh = ( ( _data16_memsz + 15 ) / 16 ); _data16_memsz_pgh = ( ( _data16_memsz + 15 ) / 16 );
} }

View File

@ -16,6 +16,7 @@ struct input_file {
struct output_file { struct output_file {
void *buf; void *buf;
size_t len; size_t len;
size_t hdr_len;
size_t max_len; size_t max_len;
}; };
@ -38,6 +39,13 @@ struct zinfo_pack {
uint32_t align; uint32_t align;
}; };
struct zinfo_payload {
char type[4];
uint32_t pad1;
uint32_t pad2;
uint32_t align;
};
struct zinfo_add { struct zinfo_add {
char type[4]; char type[4];
uint32_t offset; uint32_t offset;
@ -49,6 +57,7 @@ union zinfo_record {
struct zinfo_common common; struct zinfo_common common;
struct zinfo_copy copy; struct zinfo_copy copy;
struct zinfo_pack pack; struct zinfo_pack pack;
struct zinfo_payload payload;
struct zinfo_add add; struct zinfo_add add;
}; };
@ -209,8 +218,22 @@ static int process_zinfo_pack ( struct input_file *input,
return 0; return 0;
} }
static int process_zinfo_payl ( struct input_file *input,
struct output_file *output,
union zinfo_record *zinfo ) {
struct zinfo_payload *payload = &zinfo->payload;
output->len = align ( output->len, payload->align );
output->hdr_len = output->len;
if ( DEBUG ) {
fprintf ( stderr, "PAYL at %#zx\n", output->hdr_len );
}
}
static int process_zinfo_add ( struct input_file *input, static int process_zinfo_add ( struct input_file *input,
struct output_file *output, struct output_file *output,
size_t len,
struct zinfo_add *add, struct zinfo_add *add,
size_t datasize ) { size_t datasize ) {
size_t offset = add->offset; size_t offset = add->offset;
@ -227,7 +250,7 @@ static int process_zinfo_add ( struct input_file *input,
} }
target = ( output->buf + offset ); target = ( output->buf + offset );
size = ( align ( output->len, add->divisor ) / add->divisor ); size = ( align ( len, add->divisor ) / add->divisor );
switch ( datasize ) { switch ( datasize ) {
case 1: case 1:
@ -283,7 +306,7 @@ static int process_zinfo_add ( struct input_file *input,
fprintf ( stderr, "ADDx [%#zx,%#zx) (%s%#x+(%#zx/%#x)) = " fprintf ( stderr, "ADDx [%#zx,%#zx) (%s%#x+(%#zx/%#x)) = "
"%#lx\n", offset, ( offset + datasize ), "%#lx\n", offset, ( offset + datasize ),
( ( addend < 0 ) ? "-" : "" ), abs ( addend ), ( ( addend < 0 ) ? "-" : "" ), abs ( addend ),
output->len, add->divisor, val ); len, add->divisor, val );
} }
return 0; return 0;
@ -292,19 +315,43 @@ static int process_zinfo_add ( struct input_file *input,
static int process_zinfo_addb ( struct input_file *input, static int process_zinfo_addb ( struct input_file *input,
struct output_file *output, struct output_file *output,
union zinfo_record *zinfo ) { union zinfo_record *zinfo ) {
return process_zinfo_add ( input, output, &zinfo->add, 1 ); return process_zinfo_add ( input, output, output->len,
&zinfo->add, 1 );
} }
static int process_zinfo_addw ( struct input_file *input, static int process_zinfo_addw ( struct input_file *input,
struct output_file *output, struct output_file *output,
union zinfo_record *zinfo ) { union zinfo_record *zinfo ) {
return process_zinfo_add ( input, output, &zinfo->add, 2 ); return process_zinfo_add ( input, output, output->len,
&zinfo->add, 2 );
} }
static int process_zinfo_addl ( struct input_file *input, static int process_zinfo_addl ( struct input_file *input,
struct output_file *output, struct output_file *output,
union zinfo_record *zinfo ) { union zinfo_record *zinfo ) {
return process_zinfo_add ( input, output, &zinfo->add, 4 ); return process_zinfo_add ( input, output, output->len,
&zinfo->add, 4 );
}
static int process_zinfo_adhb ( struct input_file *input,
struct output_file *output,
union zinfo_record *zinfo ) {
return process_zinfo_add ( input, output, output->hdr_len,
&zinfo->add, 1 );
}
static int process_zinfo_adhw ( struct input_file *input,
struct output_file *output,
union zinfo_record *zinfo ) {
return process_zinfo_add ( input, output, output->hdr_len,
&zinfo->add, 2 );
}
static int process_zinfo_adhl ( struct input_file *input,
struct output_file *output,
union zinfo_record *zinfo ) {
return process_zinfo_add ( input, output, output->hdr_len,
&zinfo->add, 4 );
} }
struct zinfo_processor { struct zinfo_processor {
@ -317,9 +364,13 @@ struct zinfo_processor {
static struct zinfo_processor zinfo_processors[] = { static struct zinfo_processor zinfo_processors[] = {
{ "COPY", process_zinfo_copy }, { "COPY", process_zinfo_copy },
{ "PACK", process_zinfo_pack }, { "PACK", process_zinfo_pack },
{ "PAYL", process_zinfo_payl },
{ "ADDB", process_zinfo_addb }, { "ADDB", process_zinfo_addb },
{ "ADDW", process_zinfo_addw }, { "ADDW", process_zinfo_addw },
{ "ADDL", process_zinfo_addl }, { "ADDL", process_zinfo_addl },
{ "ADHB", process_zinfo_adhb },
{ "ADHW", process_zinfo_adhw },
{ "ADHL", process_zinfo_adhl },
}; };
static int process_zinfo ( struct input_file *input, static int process_zinfo ( struct input_file *input,