* %edx : total length of block (including any uninitialised data portion)
* Returns:
* %esi : next source physical address (will be a multiple of 16)
+ * %edi : next destination physical address (will be a multiple of 16)
* Corrupts:
* none
****************************************************************************
pushw %ds
pushw %es
pushl %ecx
- pushl %edi
/* Convert %esi and %edi to %ds:esi and %es:edi */
shrl $4, %esi
rep addr32 stosb
popw %ax
- /* Round up %esi to start of next source block */
+ /* Round up %esi and %edi to start of next blocks */
addl $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
movw %ds, %cx
shll $4, %ecx
addl %ecx, %esi
+ xorl %ecx, %ecx
+ movw %es, %cx
+ shll $4, %ecx
+ addl %ecx, %edi
/* Restore registers and return */
- popl %edi
popl %ecx
popw %es
popw %ds
/* Sanity: clear the direction flag asap */
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
/* Flatten real mode */
call flatten_real_mode
jnz 1f
movw %cs, %si
shll $4, %esi
-1: addl $_payload_lma, %esi
+1: addl %cs:payload_lma, %esi
- /* Install .text16 and .data16 */
- pushl %edi
- movzwl %ax, %edi
- shll $4, %edi
- movl $_text16_memsz, %ecx
- movl %ecx, %edx
- call install_block /* .text16 */
+ /* Install .text16.late and .data16 */
+ movl $_text16_late_filesz, %ecx
+ movl $_text16_late_memsz, %edx
+ call install_block /* .text16.late */
movzwl %bx, %edi
shll $4, %edi
movl $_data16_filesz, %ecx
movl $_data16_memsz, %edx
call install_block /* .data16 */
- popl %edi
/* Set up %ds for access to .data16 */
movw %bx, %ds
* prior to reading the E820 memory map and relocating
* properly.
*/
+ movl %ebp, %edi
movl $_textdata_filesz, %ecx
movl $_textdata_memsz, %edx
call install_block
/* Initialise librm at current location */
movw %ax, (init_librm_vector+2)
+ movl %ebp, %edi
lcall *init_librm_vector
/* Call relocate() to determine target address for relocation.
popl %edx /* discard */
/* Copy code to new location */
- pushl %edi
xorw %ax, %ax
movw %ax, %es
+ movl %ebp, %edi
es rep addr32 movsb
- popl %edi
/* Initialise librm at new location */
+ movl %ebp, %edi
lcall *init_librm_vector
#endif
.size prot_call_vector, . - prot_call_vector
#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
*
/* File split information for the compressor */
#if COMPRESS
+#define PACK_OR_COPY "PACK"
+#else
+#define PACK_OR_COPY "COPY"
+#endif
.section ".zinfo", "a", @progbits
.ascii "COPY"
.long _prefix_lma
.long _prefix_filesz
.long _max_align
- .ascii "PACK"
- .long _text16_lma
- .long _text16_filesz
+ .ascii PACK_OR_COPY
+ .long _text16_early_lma
+ .long _text16_early_filesz
.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_filesz
.long _max_align
- .ascii "PACK"
+ .ascii PACK_OR_COPY
.long _textdata_lma
.long _textdata_filesz
.long _max_align
-#else /* COMPRESS */
- .section ".zinfo", "a", @progbits
- .ascii "COPY"
- .long _prefix_lma
- .long _filesz
- .long _max_align
-#endif /* COMPRESS */
addr32 rep movsb /* PMM presence implies flat real mode */
movl %edi, decompress_to
/* Shrink ROM */
- movb $_prefix_memsz_sect, romheader_size
+ movb shrunk_rom_size, %al
+ movb %al, romheader_size
pmm_fail:
/* Restore upper register halves */
popal
.long 0
.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
*
* May be either at HIGHMEM_LOADPOINT, or within PMM-allocated block.
*
*/
- .text16 0x0 : AT ( _text16_lma ) {
+ .text16.early 0x0 : AT ( _text16_early_lma ) {
_text16 = .;
*(.text16.null)
. += 1; /* Prevent NULL being valid */
+ *(.text16.early)
+ *(.text16.early.*)
+ _etext16_early = .;
+ } .text16.late ALIGN ( _max_align ) : AT ( _text16_late_lma ) {
+ _text16_late = .;
*(.text16)
*(.text16.*)
_mtext16 = .;
} .bss.text16 (NOLOAD) : AT ( _end_lma ) {
_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 );
/*
_prefix_lma = .;
. += _prefix_filesz;
+ . = ALIGN ( _max_align );
+ _text16_early_lma = .;
+ . += _text16_early_filesz;
+
. = ALIGN ( _max_align );
_payload_lma = .;
- _text16_lma = .;
- . += _text16_filesz;
+ _text16_late_lma = .;
+ . += _text16_late_filesz;
. = ALIGN ( _max_align );
_data16_lma = .;
* 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 );
_data16_memsz_pgh = ( ( _data16_memsz + 15 ) / 16 );
}
struct output_file {
void *buf;
size_t len;
+ size_t hdr_len;
size_t max_len;
};
uint32_t align;
};
+struct zinfo_payload {
+ char type[4];
+ uint32_t pad1;
+ uint32_t pad2;
+ uint32_t align;
+};
+
struct zinfo_add {
char type[4];
uint32_t offset;
struct zinfo_common common;
struct zinfo_copy copy;
struct zinfo_pack pack;
+ struct zinfo_payload payload;
struct zinfo_add add;
};
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,
struct output_file *output,
+ size_t len,
struct zinfo_add *add,
size_t datasize ) {
size_t offset = add->offset;
}
target = ( output->buf + offset );
- size = ( align ( output->len, add->divisor ) / add->divisor );
+ size = ( align ( len, add->divisor ) / add->divisor );
switch ( datasize ) {
case 1:
fprintf ( stderr, "ADDx [%#zx,%#zx) (%s%#x+(%#zx/%#x)) = "
"%#lx\n", offset, ( offset + datasize ),
( ( addend < 0 ) ? "-" : "" ), abs ( addend ),
- output->len, add->divisor, val );
+ len, add->divisor, val );
}
return 0;
static int process_zinfo_addb ( struct input_file *input,
struct output_file *output,
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,
struct output_file *output,
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,
struct output_file *output,
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 {
static struct zinfo_processor zinfo_processors[] = {
{ "COPY", process_zinfo_copy },
{ "PACK", process_zinfo_pack },
+ { "PAYL", process_zinfo_payl },
{ "ADDB", process_zinfo_addb },
{ "ADDW", process_zinfo_addw },
{ "ADDL", process_zinfo_addl },
+ { "ADHB", process_zinfo_adhb },
+ { "ADHW", process_zinfo_adhw },
+ { "ADHL", process_zinfo_adhl },
};
static int process_zinfo ( struct input_file *input,