diff options
| author | Michael Brown | 2005-04-08 17:01:17 +0200 |
|---|---|---|
| committer | Michael Brown | 2005-04-08 17:01:17 +0200 |
| commit | 0ff80b477dcff0726ebdbed95e8a93971e59e82b (patch) | |
| tree | 860b7150212a07c24a9529ea072f3fb12700974c /src/arch/i386/scripts | |
| parent | Merged this file into HEAD (diff) | |
| download | ipxe-0ff80b477dcff0726ebdbed95e8a93971e59e82b.tar.gz ipxe-0ff80b477dcff0726ebdbed95e8a93971e59e82b.tar.xz ipxe-0ff80b477dcff0726ebdbed95e8a93971e59e82b.zip | |
Merged mcb30-realmode-redesign back to HEAD
Diffstat (limited to 'src/arch/i386/scripts')
| -rw-r--r-- | src/arch/i386/scripts/i386.lds | 263 |
1 files changed, 263 insertions, 0 deletions
diff --git a/src/arch/i386/scripts/i386.lds b/src/arch/i386/scripts/i386.lds new file mode 100644 index 000000000..4f9df5619 --- /dev/null +++ b/src/arch/i386/scripts/i386.lds @@ -0,0 +1,263 @@ +/* -*- 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,decompress,text,data}_link_addr, + * load_addr, and _max_align may be specified explicitly. If not + * specified, they will default to: + * + * _prefix_link_addr = 0 + * _decompress_link_addr = 0 + * _text_link_addr = 0 + * _data_link_addr = _text_link_addr + sizeof ( text sections ) + * _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 real-mode prefixes rely on _text_link_addr and + * _decompress_link_addr being 0, since they issue far calls into + * those sections, thus requiring that symbol_value == + * symbol_offset therein. Using the linker to calculate + * e.g. offset_setup16=setup16-_text will not work, since you then + * cannot use the reference from the prefix to setup16 to drag in + * setup16.o. Life is hard. + * + * If librm is included, then it must go at offset 0 within the + * text section. This is because librm is dual-usage: it is + * called from setup16 with %cs:0000 pointing to the start of the + * text section, and later it will be copied to base memory and + * called with %cs:0000 pointing to the start of librm. + * + * The decompressor is designed to decompress in-place. After + * calling the decompressor, the image will look exactly the same + * as the uncompressed image; the compressed data and the + * decompressor code itself will have been overwritten. + */ + + /* + * 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 = .; + + /* + * The decompressor (may be absent) + */ + + _decompress_link_addr = DEFINED ( _decompress_link_addr ) ? + _decompress_link_addr : 0; + . = _decompress_link_addr; + _decompress = .; + + .decompress : AT ( _decompress_load_offset + __decompress ) { + __decompress = .; + *(.decompress) + *(.decompress.*) + } + + _edecompress = .; + + /* + * The text sections + */ + + _text_link_addr = DEFINED ( _text_link_addr ) ? _text_link_addr : 0; + . = _text_link_addr; + _text = .; + + .text16 : AT ( _text_load_offset + __text16 ) { + __text16 = .; + + /* librm is a special case; it must go at the start of the + * text section if it is included. + */ + _assert = ASSERT ( ( . == _text_link_addr ), "librm cannot go first" ); + *(.librm) + + *(.text16) + *(.text16.*) + } = 0x9090 + + .text : AT ( _text_load_offset + __text ) { + __text = .; + *(.text) + *(.text.*) + } = 0x9090 + + _etext = .; + + /* + * The data sections + */ + + _data_link_addr = DEFINED ( _data_link_addr ) ? _data_link_addr : .; + . = _data_link_addr; + _data = .; + + .rodata : AT ( _data_load_offset + __rodata ) { + __rodata = .; + *(.rodata) + *(.rodata.*) + } + + .data : AT ( _data_load_offset + __data ) { + __data = .; + *(.data) + *(.data.*) + pci_drivers = .; + *(.drivers.pci) + pci_drivers_end = .; + isa_drivers = .; + *(.drivers.isa) + isa_drivers_end = .; + console_drivers = .; + *(.drivers.console) + console_drivers_end = .; + init_fns = .; + *(SORT(.init_fns.*)) + init_fns_end = .; + + _progbits_end = .; + } + + .bss : AT ( _data_load_offset + __bss ) { + __bss = .; + _bss = .; + *(.bss) + *(.bss.*) + *(COMMON) + _ebss = .; + } + + .stack : AT ( _data_load_offset + __stack ) { + __stack = .; + *(.stack) + *(.stack.*) + } + + _edata = .; + + _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_load_addr + _prefix_size; + + . -= _decompress_link_addr; + _decompress_load_offset = ALIGN ( _max_align ); + _decompress_load_addr = _decompress_link_addr + _decompress_load_offset; + _decompress_size = _edecompress - _decompress; + . = _decompress_load_addr + _decompress_size; + + . -= _text_link_addr; + _text_load_offset = ALIGN ( _max_align ); + _text_load_addr = _text_link_addr + _text_load_offset; + _text_size = _etext - _text; + . = _text_load_addr + _text_size; + + . -= _data_link_addr; + _data_load_offset = ALIGN ( _max_align ); + _data_load_addr = _data_link_addr + _data_load_offset; + _data_size = _edata - _data; + . = _data_load_addr + _data_size; + + /* + * 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" ); + + . = _decompress_load_addr - _prefix_link_addr; + _assert = ASSERT ( ( . == ALIGN ( _max_align ) ), + "_decompress is badly aligned" ); + + . = _text_load_addr - _text_link_addr; + _assert = ASSERT ( ( . == ALIGN ( _max_align ) ), + "_text is badly aligned" ); + + . = _data_load_addr - _data_link_addr; + _assert = ASSERT ( ( . == ALIGN ( _max_align ) ), + "_data is badly aligned" ); + + /* + * setup16 needs to know this when KEEP_IT_REAL is used. There + * are no harmful side-effects of calculating it all the time. + */ + _text_load_size_pgh = ( _data_load_addr - _text_load_addr ) / 16 ; + + /* + * Useful-to-know values. + */ + + /* Size of the decompressed runtime image */ + _runtime_size = _edata - _text; + /* Size of the initialised-contents portion of the runtime image */ + _runtime_progbits_size = _progbits_end - _text; + /* Size of the (non-compressed) binary file */ + _file_size = _prefix_size + _runtime_progbits_size; + /* Size of the non-compressed portion of the compressed binary file */ + _zfile_noncompressed_size = _prefix_size + _decompress_size; +} |
