[prefix] Add .text16.early section
authorMichael Brown <mcb30@ipxe.org>
Tue, 20 Apr 2010 10:05:53 +0000 (11:05 +0100)
committerStefan Hajnoczi <stefanha@gmail.com>
Wed, 7 Jul 2010 19:14:36 +0000 (20:14 +0100)
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>
Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com>
src/arch/i386/prefix/libprefix.S
src/arch/i386/prefix/romprefix.S
src/arch/i386/scripts/i386.lds
src/util/zbin.c

index 4decb01..b820f2a 100644 (file)
@@ -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 */
index bab8f47..8127053 100644 (file)
@@ -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.
index 77e8c7e..7c55c2f 100644 (file)
@@ -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 );
 }
index 707ae99..f0df5ea 100644 (file)
@@ -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,