Browse Source

[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>
tags/v1.20.1
Michael Brown 14 years ago
parent
commit
9068249e24
4 changed files with 150 additions and 39 deletions
  1. 63
    27
      src/arch/i386/prefix/libprefix.S
  2. 15
    1
      src/arch/i386/prefix/romprefix.S
  3. 16
    6
      src/arch/i386/scripts/i386.lds
  4. 56
    5
      src/util/zbin.c

+ 63
- 27
src/arch/i386/prefix/libprefix.S View File

@@ -406,6 +406,7 @@ copy_bytes:
406 406
  *   %edx : total length of block (including any uninitialised data portion)
407 407
  * Returns:
408 408
  *   %esi : next source physical address (will be a multiple of 16)
409
+ *   %edi : next destination physical address (will be a multiple of 16)
409 410
  * Corrupts:
410 411
  *   none
411 412
  ****************************************************************************
@@ -417,7 +418,6 @@ install_block:
417 418
 	pushw	%ds
418 419
 	pushw	%es
419 420
 	pushl	%ecx
420
-	pushl	%edi
421 421
 	
422 422
 	/* Convert %esi and %edi to %ds:esi and %es:edi */
423 423
 	shrl	$4, %esi
@@ -445,18 +445,23 @@ install_block:
445 445
 	rep addr32 stosb
446 446
 	popw	%ax
447 447
 
448
-	/* Round up %esi to start of next source block */
448
+	/* Round up %esi and %edi to start of next blocks */
449 449
 	addl	$0xf, %esi
450 450
 	andl	$~0xf, %esi
451
+	addl	$0xf, %edi
452
+	andl	$~0xf, %edi
451 453
 
452
-	/* Convert %ds:esi back to a physical address */
454
+	/* Convert %ds:esi and %es:edi back to physical addresses */
453 455
 	xorl	%ecx, %ecx
454 456
 	movw	%ds, %cx
455 457
 	shll	$4, %ecx
456 458
 	addl	%ecx, %esi
459
+	xorl	%ecx, %ecx
460
+	movw	%es, %cx
461
+	shll	$4, %ecx
462
+	addl	%ecx, %edi
457 463
 
458 464
 	/* Restore registers and return */
459
-	popl	%edi
460 465
 	popl	%ecx
461 466
 	popw	%es
462 467
 	popw	%ds
@@ -626,6 +631,23 @@ install_prealloc:
626 631
 	/* Sanity: clear the direction flag asap */
627 632
 	cld
628 633
 
634
+	/* Copy decompression temporary area physical address to %ebp */
635
+	movl	%edi, %ebp
636
+
637
+	/* Install .text16.early */
638
+	pushl	%esi
639
+	xorl	%esi, %esi
640
+	movw	%cs, %si
641
+	shll	$4, %esi
642
+	addl	$_text16_early_lma, %esi
643
+	movzwl	%ax, %edi
644
+	shll	$4, %edi
645
+	movl	$_text16_early_filesz, %ecx
646
+	movl	$_text16_early_memsz, %edx
647
+	call	install_block		/* .text16.early */
648
+	popl	%esi
649
+
650
+	/* Open up access to payload */
629 651
 #ifndef KEEP_IT_REAL
630 652
 	/* Flatten real mode */
631 653
 	call	flatten_real_mode
@@ -636,21 +658,17 @@ install_prealloc:
636 658
 	jnz	1f
637 659
 	movw	%cs, %si
638 660
 	shll	$4, %esi
639
-1:	addl	$_payload_lma, %esi
661
+1:	addl	%cs:payload_lma, %esi
640 662
 
641
-	/* Install .text16 and .data16 */
642
-	pushl	%edi
643
-	movzwl	%ax, %edi
644
-	shll	$4, %edi
645
-	movl	$_text16_memsz, %ecx
646
-	movl	%ecx, %edx
647
-	call	install_block		/* .text16 */
663
+	/* Install .text16.late and .data16 */
664
+	movl	$_text16_late_filesz, %ecx
665
+	movl	$_text16_late_memsz, %edx
666
+	call	install_block		/* .text16.late */
648 667
 	movzwl	%bx, %edi
649 668
 	shll	$4, %edi
650 669
 	movl	$_data16_filesz, %ecx
651 670
 	movl	$_data16_memsz, %edx
652 671
 	call	install_block		/* .data16 */
653
-	popl	%edi
654 672
 
655 673
 	/* Set up %ds for access to .data16 */
656 674
 	movw	%bx, %ds
@@ -664,12 +682,14 @@ install_prealloc:
664 682
 	 * prior to reading the E820 memory map and relocating
665 683
 	 * properly.
666 684
 	 */
685
+	movl	%ebp, %edi
667 686
 	movl	$_textdata_filesz, %ecx
668 687
 	movl	$_textdata_memsz, %edx
669 688
 	call	install_block
670 689
 
671 690
 	/* Initialise librm at current location */
672 691
 	movw	%ax, (init_librm_vector+2)
692
+	movl	%ebp, %edi
673 693
 	lcall	*init_librm_vector
674 694
 
675 695
 	/* Call relocate() to determine target address for relocation.
@@ -682,13 +702,13 @@ install_prealloc:
682 702
 	popl	%edx /* discard */
683 703
 
684 704
 	/* Copy code to new location */
685
-	pushl	%edi
686 705
 	xorw	%ax, %ax
687 706
 	movw	%ax, %es
707
+	movl	%ebp, %edi
688 708
 	es rep addr32 movsb
689
-	popl	%edi
690 709
 
691 710
 	/* Initialise librm at new location */
711
+	movl	%ebp, %edi
692 712
 	lcall	*init_librm_vector
693 713
 #endif
694 714
 
@@ -719,6 +739,17 @@ prot_call_vector:
719 739
 	.size prot_call_vector, . - prot_call_vector
720 740
 #endif
721 741
 
742
+	/* Payload address */
743
+	.section ".prefix.lib", "awx", @progbits
744
+payload_lma:
745
+	.long 0
746
+	.section ".zinfo.fixup", "a", @progbits	/* Compressor fixups */
747
+	.ascii	"ADHL"
748
+	.long	payload_lma
749
+	.long	1
750
+	.long	0
751
+	.previous
752
+
722 753
 /****************************************************************************
723 754
  * uninstall
724 755
  *
@@ -745,27 +776,32 @@ uninstall:
745 776
 
746 777
 	/* File split information for the compressor */
747 778
 #if COMPRESS
779
+#define PACK_OR_COPY	"PACK"
780
+#else
781
+#define PACK_OR_COPY	"COPY"
782
+#endif
748 783
 	.section ".zinfo", "a", @progbits
749 784
 	.ascii	"COPY"
750 785
 	.long	_prefix_lma
751 786
 	.long	_prefix_filesz
752 787
 	.long	_max_align
753
-	.ascii	"PACK"
754
-	.long	_text16_lma
755
-	.long	_text16_filesz
788
+	.ascii	PACK_OR_COPY
789
+	.long	_text16_early_lma
790
+	.long	_text16_early_filesz
756 791
 	.long	_max_align
757
-	.ascii	"PACK"
792
+	.ascii	"PAYL"
793
+	.long	0
794
+	.long	0
795
+	.long	_max_align
796
+	.ascii	PACK_OR_COPY
797
+	.long	_text16_late_lma
798
+	.long	_text16_late_filesz
799
+	.long	_max_align
800
+	.ascii	PACK_OR_COPY
758 801
 	.long	_data16_lma
759 802
 	.long	_data16_filesz
760 803
 	.long	_max_align
761
-	.ascii	"PACK"
804
+	.ascii	PACK_OR_COPY
762 805
 	.long	_textdata_lma
763 806
 	.long	_textdata_filesz
764 807
 	.long	_max_align
765
-#else /* COMPRESS */
766
-	.section ".zinfo", "a", @progbits
767
-	.ascii	"COPY"
768
-	.long	_prefix_lma
769
-	.long	_filesz
770
-	.long	_max_align
771
-#endif /* COMPRESS */

+ 15
- 1
src/arch/i386/prefix/romprefix.S View File

@@ -362,7 +362,8 @@ got_pmm: /* PMM allocation succeeded */
362 362
 	addr32 rep movsb	/* PMM presence implies flat real mode */
363 363
 	movl	%edi, decompress_to
364 364
 	/* Shrink ROM */
365
-	movb	$_prefix_memsz_sect, romheader_size
365
+	movb	shrunk_rom_size, %al
366
+	movb	%al, romheader_size
366 367
 pmm_fail:
367 368
 	/* Restore upper register halves */
368 369
 	popal
@@ -488,6 +489,19 @@ image_source:
488 489
 	.long	0
489 490
 	.size	image_source, . - image_source
490 491
 
492
+/* Shrunk ROM size (in 512-byte sectors)
493
+ *
494
+ */
495
+shrunk_rom_size:
496
+	.byte	0
497
+	.size	shrunk_rom_size, . - shrunk_rom_size
498
+	.section ".zinfo.fixup", "a", @progbits	/* Compressor fixups */
499
+	.ascii	"ADHB"
500
+	.long	shrunk_rom_size
501
+	.long	512
502
+	.long	0
503
+	.previous
504
+
491 505
 /* Temporary decompression area
492 506
  *
493 507
  * May be either at HIGHMEM_LOADPOINT, or within PMM-allocated block.

+ 16
- 6
src/arch/i386/scripts/i386.lds View File

@@ -45,17 +45,25 @@ SECTIONS {
45 45
      *
46 46
      */
47 47
 
48
-    .text16 0x0 : AT ( _text16_lma ) {
48
+    .text16.early 0x0 : AT ( _text16_early_lma ) {
49 49
 	_text16 = .;
50 50
 	*(.text16.null)
51 51
 	. += 1;				/* Prevent NULL being valid */
52
+	*(.text16.early)
53
+	*(.text16.early.*)
54
+	_etext16_early = .;
55
+    } .text16.late ALIGN ( _max_align ) : AT ( _text16_late_lma ) {
56
+	_text16_late = .;
52 57
 	*(.text16)
53 58
 	*(.text16.*)
54 59
 	_mtext16 = .;
55 60
     } .bss.text16 (NOLOAD) : AT ( _end_lma ) {
56 61
 	_etext16 = .;
57 62
     }
58
-    _text16_filesz	= ABSOLUTE ( _mtext16 - _text16 );
63
+    _text16_early_filesz = ABSOLUTE ( _etext16_early - _text16 );
64
+    _text16_early_memsz	= ABSOLUTE ( _etext16_early - _text16 );
65
+    _text16_late_filesz	= ABSOLUTE ( _mtext16 - _text16_late );
66
+    _text16_late_memsz	= ABSOLUTE ( _etext16 - _text16_late );
59 67
     _text16_memsz	= ABSOLUTE ( _etext16 - _text16 );
60 68
 
61 69
     /*
@@ -168,10 +176,14 @@ SECTIONS {
168 176
     _prefix_lma		= .;
169 177
     .			+= _prefix_filesz;
170 178
 
179
+    .			= ALIGN ( _max_align );
180
+    _text16_early_lma	= .;
181
+    .			+= _text16_early_filesz;
182
+
171 183
     .			= ALIGN ( _max_align );
172 184
     _payload_lma	= .;
173
-    _text16_lma		= .;
174
-    .			+= _text16_filesz;
185
+    _text16_late_lma	= .;
186
+    .			+= _text16_late_filesz;
175 187
 
176 188
     .			= ALIGN ( _max_align );
177 189
     _data16_lma		= .;
@@ -194,8 +206,6 @@ SECTIONS {
194 206
      * Values calculated to save code from doing it
195 207
      *
196 208
      */
197
-    _prefix_memsz_pgh	= ( ( _prefix_memsz + 15 ) / 16 );
198
-    _prefix_memsz_sect	= ( ( _prefix_memsz + 511 ) / 512 );
199 209
     _text16_memsz_pgh	= ( ( _text16_memsz + 15 ) / 16 );
200 210
     _data16_memsz_pgh	= ( ( _data16_memsz + 15 ) / 16 );
201 211
 }

+ 56
- 5
src/util/zbin.c View File

@@ -16,6 +16,7 @@ struct input_file {
16 16
 struct output_file {
17 17
 	void *buf;
18 18
 	size_t len;
19
+	size_t hdr_len;
19 20
 	size_t max_len;
20 21
 };
21 22
 
@@ -38,6 +39,13 @@ struct zinfo_pack {
38 39
 	uint32_t align;
39 40
 };
40 41
 
42
+struct zinfo_payload {
43
+	char type[4];
44
+	uint32_t pad1;
45
+	uint32_t pad2;
46
+	uint32_t align;
47
+};
48
+
41 49
 struct zinfo_add {
42 50
 	char type[4];
43 51
 	uint32_t offset;
@@ -49,6 +57,7 @@ union zinfo_record {
49 57
 	struct zinfo_common common;
50 58
 	struct zinfo_copy copy;
51 59
 	struct zinfo_pack pack;
60
+	struct zinfo_payload payload;
52 61
 	struct zinfo_add add;
53 62
 };
54 63
 
@@ -209,8 +218,22 @@ static int process_zinfo_pack ( struct input_file *input,
209 218
 	return 0;
210 219
 }
211 220
 
221
+static int process_zinfo_payl ( struct input_file *input,
222
+				struct output_file *output,
223
+				union zinfo_record *zinfo ) {
224
+	struct zinfo_payload *payload = &zinfo->payload;
225
+
226
+	output->len = align ( output->len, payload->align );
227
+	output->hdr_len = output->len;
228
+
229
+	if ( DEBUG ) {
230
+		fprintf ( stderr, "PAYL at %#zx\n", output->hdr_len );
231
+	}
232
+}
233
+
212 234
 static int process_zinfo_add ( struct input_file *input,
213 235
 			       struct output_file *output,
236
+			       size_t len,
214 237
 			       struct zinfo_add *add,
215 238
 			       size_t datasize ) {
216 239
 	size_t offset = add->offset;
@@ -227,7 +250,7 @@ static int process_zinfo_add ( struct input_file *input,
227 250
 	}
228 251
 
229 252
 	target = ( output->buf + offset );
230
-	size = ( align ( output->len, add->divisor ) / add->divisor );
253
+	size = ( align ( len, add->divisor ) / add->divisor );
231 254
 
232 255
 	switch ( datasize ) {
233 256
 	case 1:
@@ -283,7 +306,7 @@ static int process_zinfo_add ( struct input_file *input,
283 306
 		fprintf ( stderr, "ADDx [%#zx,%#zx) (%s%#x+(%#zx/%#x)) = "
284 307
 			  "%#lx\n", offset, ( offset + datasize ),
285 308
 			  ( ( addend < 0 ) ? "-" : "" ), abs ( addend ),
286
-			  output->len, add->divisor, val );
309
+			  len, add->divisor, val );
287 310
 	}
288 311
 
289 312
 	return 0;
@@ -292,19 +315,43 @@ static int process_zinfo_add ( struct input_file *input,
292 315
 static int process_zinfo_addb ( struct input_file *input,
293 316
 				struct output_file *output,
294 317
 				union zinfo_record *zinfo ) {
295
-	return process_zinfo_add ( input, output, &zinfo->add, 1 );
318
+	return process_zinfo_add ( input, output, output->len,
319
+				   &zinfo->add, 1 );
296 320
 }
297 321
 
298 322
 static int process_zinfo_addw ( struct input_file *input,
299 323
 				struct output_file *output,
300 324
 				union zinfo_record *zinfo ) {
301
-	return process_zinfo_add ( input, output, &zinfo->add, 2 );
325
+	return process_zinfo_add ( input, output, output->len,
326
+				   &zinfo->add, 2 );
302 327
 }
303 328
 
304 329
 static int process_zinfo_addl ( struct input_file *input,
305 330
 				struct output_file *output,
306 331
 				union zinfo_record *zinfo ) {
307
-	return process_zinfo_add ( input, output, &zinfo->add, 4 );
332
+	return process_zinfo_add ( input, output, output->len,
333
+				   &zinfo->add, 4 );
334
+}
335
+
336
+static int process_zinfo_adhb ( struct input_file *input,
337
+				struct output_file *output,
338
+				union zinfo_record *zinfo ) {
339
+	return process_zinfo_add ( input, output, output->hdr_len,
340
+				   &zinfo->add, 1 );
341
+}
342
+
343
+static int process_zinfo_adhw ( struct input_file *input,
344
+				struct output_file *output,
345
+				union zinfo_record *zinfo ) {
346
+	return process_zinfo_add ( input, output, output->hdr_len,
347
+				   &zinfo->add, 2 );
348
+}
349
+
350
+static int process_zinfo_adhl ( struct input_file *input,
351
+				struct output_file *output,
352
+				union zinfo_record *zinfo ) {
353
+	return process_zinfo_add ( input, output, output->hdr_len,
354
+				   &zinfo->add, 4 );
308 355
 }
309 356
 
310 357
 struct zinfo_processor {
@@ -317,9 +364,13 @@ struct zinfo_processor {
317 364
 static struct zinfo_processor zinfo_processors[] = {
318 365
 	{ "COPY", process_zinfo_copy },
319 366
 	{ "PACK", process_zinfo_pack },
367
+	{ "PAYL", process_zinfo_payl },
320 368
 	{ "ADDB", process_zinfo_addb },
321 369
 	{ "ADDW", process_zinfo_addw },
322 370
 	{ "ADDL", process_zinfo_addl },
371
+	{ "ADHB", process_zinfo_adhb },
372
+	{ "ADHW", process_zinfo_adhw },
373
+	{ "ADHL", process_zinfo_adhl },
323 374
 };
324 375
 
325 376
 static int process_zinfo ( struct input_file *input,

Loading…
Cancel
Save