david/ipxe
david
/
ipxe
Archived
1
0
Fork 0
This repository has been archived on 2020-12-06. You can view files and clone it, but cannot push or open issues or pull requests.
ipxe/src/arch/i386/scripts/i386.lds

264 lines
7.4 KiB
Plaintext

/* -*- 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;
}