diff options
author | Michael Brown <mcb30@etherboot.org> | 2006-08-24 13:18:05 +0000 |
---|---|---|
committer | Michael Brown <mcb30@etherboot.org> | 2006-08-24 13:18:05 +0000 |
commit | 6abfaa153b7b9bcdbdfc8b842ebb3ec99428d69b (patch) | |
tree | 72f551c4156a9dd85d48099f905daccdb12a5933 /src/arch/i386/scripts | |
parent | cddf8df8d4522f2fbc42520e9bfde9325caf0f56 (diff) | |
download | ipxe-6abfaa153b7b9bcdbdfc8b842ebb3ec99428d69b.zip ipxe-6abfaa153b7b9bcdbdfc8b842ebb3ec99428d69b.tar.gz ipxe-6abfaa153b7b9bcdbdfc8b842ebb3ec99428d69b.tar.bz2 |
Towards making KEEP_IT_REAL work again.
Fix bug that caused over-allocation of .text16 and .data16 memory areas
by a factor of 16.
Diffstat (limited to 'src/arch/i386/scripts')
-rw-r--r-- | src/arch/i386/scripts/i386-kir.lds | 192 | ||||
-rw-r--r-- | src/arch/i386/scripts/i386.lds | 6 |
2 files changed, 196 insertions, 2 deletions
diff --git a/src/arch/i386/scripts/i386-kir.lds b/src/arch/i386/scripts/i386-kir.lds new file mode 100644 index 0000000..3095b31 --- /dev/null +++ b/src/arch/i386/scripts/i386-kir.lds @@ -0,0 +1,192 @@ +/* -*- sh -*- */ + +/* + * Linker script for i386 images + * + */ + +OUTPUT_FORMAT ( "elf32-i386", "elf32-i386", "elf32-i386" ) +OUTPUT_ARCH ( i386 ) +ENTRY ( _entry ) + +SECTIONS { + + /* All sections in the resulting file have consecutive load + * addresses, but may have individual link addresses depending on + * the memory model being used. + * + * The linker symbols _prefix_link_addr, load_addr, and + * _max_align may be specified explicitly. If not specified, they + * will default to: + * + * _prefix_link_addr = 0 + * _load_addr = 0 + * _max_align = 16 + * + * We guarantee alignment of virtual addresses to any alignment + * specified by the constituent object files (e.g. via + * __attribute__((aligned(x)))). Load addresses are guaranteed + * only up to _max_align. Provided that all loader and relocation + * code honours _max_align, this means that physical addresses are + * also guaranteed up to _max_align. + * + * Note that when using -DKEEP_IT_REAL, the UNDI segments are only + * guaranteed to be loaded on a paragraph boundary (i.e. 16-byte + * alignment). Using _max_align>16 will therefore not guarantee + * >16-byte alignment of physical addresses when -DKEEP_IT_REAL is + * used (though virtual addresses will still be fully aligned). + * + */ + + /* + * The prefix + */ + + _prefix_link_addr = DEFINED ( _prefix_link_addr ) ? _prefix_link_addr : 0; + . = _prefix_link_addr; + _prefix = .; + + .prefix : AT ( _prefix_load_offset + __prefix ) { + __prefix = .; + _entry = .; + *(.prefix) + *(.prefix.*) + _eprefix_progbits = .; + } + + _eprefix = .; + + /* + * The 16-bit sections + */ + + _text16_link_addr = 0; + . = _text16_link_addr; + _text16 = .; + + .text16 : AT ( _text16_load_offset + __text16 ) { + __text16 = .; + *(.text.null_trap) + *(.text16) + *(.text16.*) + *(.text) + *(.text.*) + _etext16_progbits = .; + } = 0x9090 + + _etext16 = .; + + _data16_link_addr = 0; + . = _data16_link_addr; + _data16 = .; + + .rodata16 : AT ( _data16_load_offset + __rodata16 ) { + __rodata16 = .; + *(.rodata16) + *(.rodata16.*) + *(.rodata) + *(.rodata.*) + } + .data16 : AT ( _data16_load_offset + __data16 ) { + __data16 = .; + *(.data16) + *(.data16.*) + *(.data) + *(.data.*) + *(SORT(.tbl.*)) /* Various tables. See include/tables.h */ + _edata16_progbits = .; + } + .bss16 : AT ( _data16_load_offset + __bss16 ) { + __bss16 = .; + _bss16 = .; + *(.bss16) + *(.bss16.*) + *(.bss) + *(.bss.*) + *(COMMON) + _ebss16 = .; + } + .stack16 : AT ( _data16_load_offset + __stack16 ) { + __stack16 = .; + *(.stack16) + *(.stack16.*) + *(.stack) + *(.stack.*) + } + + _edata16 = .; + + _end = .; + + /* + * Dispose of the comment and note sections to make the link map + * easier to read + */ + + /DISCARD/ : { + *(.comment) + *(.note) + } + + /* + * Load address calculations. The slightly obscure nature of the + * calculations is because ALIGN(x) can only operate on the + * location counter. + */ + + _max_align = DEFINED ( _max_align ) ? _max_align : 16; + _load_addr = DEFINED ( _load_addr ) ? _load_addr : 0; + + . = _load_addr; + + . -= _prefix_link_addr; + _prefix_load_offset = ALIGN ( _max_align ); + _prefix_load_addr = _prefix_link_addr + _prefix_load_offset; + _prefix_size = _eprefix - _prefix; + _prefix_progbits_size = _eprefix_progbits - _prefix; + . = _prefix_load_addr + _prefix_progbits_size; + + . -= _text16_link_addr; + _text16_load_offset = ALIGN ( _max_align ); + _text16_load_addr = _text16_link_addr + _text16_load_offset; + _text16_size = _etext16 - _text16; + _text16_progbits_size = _etext16_progbits - _text16; + . = _text16_load_addr + _text16_progbits_size; + + . -= _data16_link_addr; + _data16_load_offset = ALIGN ( _max_align ); + _data16_load_addr = _data16_link_addr + _data16_load_offset; + _data16_size = _edata16 - _data16; + _data16_progbits_size = _edata16_progbits - _data16; + . = _data16_load_addr + _data16_progbits_size; + + . = ALIGN ( _max_align ); + + _load_size = . - _load_addr; + + /* + * Alignment checks. ALIGN() can only operate on the location + * counter, so we set the location counter to each value we want + * to check. + */ + + . = _prefix_load_addr - _prefix_link_addr; + _assert = ASSERT ( ( . == ALIGN ( _max_align ) ), + "_prefix is badly aligned" ); + + . = _text16_load_addr - _text16_link_addr; + _assert = ASSERT ( ( . == ALIGN ( _max_align ) ), + "_text16 is badly aligned" ); + + . = _data16_load_addr - _data16_link_addr; + _assert = ASSERT ( ( . == ALIGN ( _max_align ) ), + "_data16 is badly aligned" ); + + /* + * Values calculated to save code from doing it + */ + _text16_size_pgh = ( ( _text16_size + 15 ) / 16 ); + _data16_size_pgh = ( ( _data16_size + 15 ) / 16 ); + _load_size_pgh = ( ( _load_size + 15 ) / 16 ); + _rom_size = ( ( _load_size + 511 ) / 512 ); +} diff --git a/src/arch/i386/scripts/i386.lds b/src/arch/i386/scripts/i386.lds index 48dd777..3077609 100644 --- a/src/arch/i386/scripts/i386.lds +++ b/src/arch/i386/scripts/i386.lds @@ -15,7 +15,7 @@ SECTIONS { * addresses, but may have individual link addresses depending on * the memory model being used. * - * The linker symbols {prefix,text}_link_addr, load_addr, and + * The linker symbols _{prefix,textdata}_link_addr, load_addr, and * _max_align may be specified explicitly. If not specified, they * will default to: * @@ -236,6 +236,8 @@ SECTIONS { /* * Values calculated to save code from doing it */ - _load_size_pgh = ( _load_size / 16 ); + _text16_size_pgh = ( ( _text16_size + 15 ) / 16 ); + _data16_size_pgh = ( ( _data16_size + 15 ) / 16 ); + _load_size_pgh = ( ( _load_size + 15 ) / 16 ); _rom_size = ( ( _load_size + 511 ) / 512 ); } |