diff --git a/src/arch/i386/prefix/libprefix.S b/src/arch/i386/prefix/libprefix.S index 4decb013..b820f2a3 100644 --- a/src/arch/i386/prefix/libprefix.S +++ b/src/arch/i386/prefix/libprefix.S @@ -406,6 +406,7 @@ copy_bytes: * %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 **************************************************************************** @@ -417,7 +418,6 @@ install_block: pushw %ds pushw %es pushl %ecx - pushl %edi /* Convert %esi and %edi to %ds:esi and %es:edi */ shrl $4, %esi @@ -445,18 +445,23 @@ install_block: 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 @@ -626,6 +631,23 @@ install_prealloc: /* 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 @@ -636,21 +658,17 @@ install_prealloc: 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 @@ -664,12 +682,14 @@ install_prealloc: * 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. @@ -682,13 +702,13 @@ install_prealloc: 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 @@ -719,6 +739,17 @@ prot_call_vector: .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 * @@ -745,27 +776,32 @@ 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 */ diff --git a/src/arch/i386/prefix/romprefix.S b/src/arch/i386/prefix/romprefix.S index 2d70cd21..3fec7327 100644 --- a/src/arch/i386/prefix/romprefix.S +++ b/src/arch/i386/prefix/romprefix.S @@ -362,7 +362,8 @@ got_pmm: /* PMM allocation succeeded */ 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 @@ -488,6 +489,19 @@ image_source: .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. diff --git a/src/arch/i386/scripts/i386.lds b/src/arch/i386/scripts/i386.lds index 77e8c7e7..7c55c2f6 100644 --- a/src/arch/i386/scripts/i386.lds +++ b/src/arch/i386/scripts/i386.lds @@ -45,17 +45,25 @@ SECTIONS { * */ - .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 ); /* @@ -168,10 +176,14 @@ SECTIONS { _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 = .; @@ -194,8 +206,6 @@ SECTIONS { * 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 ); } diff --git a/src/util/zbin.c b/src/util/zbin.c index 707ae995..f0df5ea0 100644 --- a/src/util/zbin.c +++ b/src/util/zbin.c @@ -16,6 +16,7 @@ struct input_file { struct output_file { void *buf; size_t len; + size_t hdr_len; size_t max_len; }; @@ -38,6 +39,13 @@ struct zinfo_pack { 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; @@ -49,6 +57,7 @@ union zinfo_record { struct zinfo_common common; struct zinfo_copy copy; struct zinfo_pack pack; + struct zinfo_payload payload; struct zinfo_add add; }; @@ -209,8 +218,22 @@ static int process_zinfo_pack ( struct input_file *input, 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; @@ -227,7 +250,7 @@ static int process_zinfo_add ( struct input_file *input, } target = ( output->buf + offset ); - size = ( align ( output->len, add->divisor ) / add->divisor ); + size = ( align ( len, add->divisor ) / add->divisor ); switch ( datasize ) { case 1: @@ -283,7 +306,7 @@ static int process_zinfo_add ( struct input_file *input, 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; @@ -292,19 +315,43 @@ static int process_zinfo_add ( struct input_file *input, 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 { @@ -317,9 +364,13 @@ 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,