4 * Linker script for i386 images
8 OUTPUT_FORMAT ( "elf32-i386", "elf32-i386", "elf32-i386" )
14 /* All sections in the resulting file have consecutive load
15 * addresses, but may have individual link addresses depending on
16 * the memory model being used.
18 * The linker symbols _{prefix,textdata}_link_addr, load_addr, and
19 * _max_align may be specified explicitly. If not specified, they
22 * _prefix_link_addr = 0
23 * _textdata_link_addr = 0
27 * We guarantee alignment of virtual addresses to any alignment
28 * specified by the constituent object files (e.g. via
29 * __attribute__((aligned(x)))). Load addresses are guaranteed
30 * only up to _max_align. Provided that all loader and relocation
31 * code honours _max_align, this means that physical addresses are
32 * also guaranteed up to _max_align.
34 * Note that when using -DKEEP_IT_REAL, the UNDI segments are only
35 * guaranteed to be loaded on a paragraph boundary (i.e. 16-byte
36 * alignment). Using _max_align>16 will therefore not guarantee
37 * >16-byte alignment of physical addresses when -DKEEP_IT_REAL is
38 * used (though virtual addresses will still be fully aligned).
46 _prefix_link_addr = DEFINED ( _prefix_link_addr ) ? _prefix_link_addr : 0;
47 . = _prefix_link_addr;
50 .prefix : AT ( _prefix_load_offset + __prefix ) {
55 _eprefix_progbits = .;
61 * The 16-bit sections, if present
64 _text16_link_addr = 0;
65 . = _text16_link_addr;
68 . += 1; /* Prevent NULL being valid */
70 .text16 : AT ( _text16_load_offset + __text16 ) {
74 _etext16_progbits = .;
79 _data16_link_addr = 0;
80 . = _data16_link_addr;
83 . += 1; /* Prevent NULL being valid */
85 .rodata16 : AT ( _data16_load_offset + __rodata16 ) {
90 .data16 : AT ( _data16_load_offset + __data16 ) {
94 _edata16_progbits = .;
96 .bss16 : AT ( _data16_load_offset + __bss16 ) {
103 .stack16 : AT ( _data16_load_offset + __stack16 ) {
112 * The 32-bit sections
115 _textdata_link_addr = ( DEFINED ( _textdata_link_addr ) ?
116 _textdata_link_addr : 0 );
117 . = _textdata_link_addr;
122 . += 1; /* Prevent NULL being valid */
124 .text : AT ( _textdata_load_offset + __text ) {
135 .rodata : AT ( _textdata_load_offset + __rodata ) {
140 .data : AT ( _textdata_load_offset + __data ) {
144 *(SORT(.tbl.*)) /* Various tables. See include/tables.h */
145 _etextdata_progbits = .;
147 .bss : AT ( _textdata_load_offset + __bss ) {
155 .stack : AT ( _textdata_load_offset + __stack ) {
168 * Dispose of the comment and note sections to make the link map
178 * Load address calculations. The slightly obscure nature of the
179 * calculations is because ALIGN(x) can only operate on the
183 _max_align = DEFINED ( _max_align ) ? _max_align : 16;
184 _load_addr = DEFINED ( _load_addr ) ? _load_addr : 0;
188 . -= _prefix_link_addr;
189 _prefix_load_offset = ALIGN ( _max_align );
190 _prefix_load_addr = _prefix_link_addr + _prefix_load_offset;
191 _prefix_size = _eprefix - _prefix;
192 _prefix_progbits_size = _eprefix_progbits - _prefix;
193 . = _prefix_load_addr + _prefix_progbits_size;
195 . -= _text16_link_addr;
196 _text16_load_offset = ALIGN ( _max_align );
197 _text16_load_addr = _text16_link_addr + _text16_load_offset;
198 _text16_size = _etext16 - _text16;
199 _text16_progbits_size = _etext16_progbits - _text16;
200 . = _text16_load_addr + _text16_progbits_size;
202 . -= _data16_link_addr;
203 _data16_load_offset = ALIGN ( _max_align );
204 _data16_load_addr = _data16_link_addr + _data16_load_offset;
205 _data16_size = _edata16 - _data16;
206 _data16_progbits_size = _edata16_progbits - _data16;
207 . = _data16_load_addr + _data16_progbits_size;
209 . -= _textdata_link_addr;
210 _textdata_load_offset = ALIGN ( _max_align );
211 _textdata_load_addr = _textdata_link_addr + _textdata_load_offset;
212 _textdata_size = _etextdata - _textdata;
213 _textdata_progbits_size = _etextdata_progbits - _textdata;
214 . = _textdata_load_addr + _textdata_progbits_size;
216 . = ALIGN ( _max_align );
218 _load_size = . - _load_addr;
221 * Alignment checks. ALIGN() can only operate on the location
222 * counter, so we set the location counter to each value we want
226 . = _prefix_load_addr - _prefix_link_addr;
227 _assert = ASSERT ( ( . == ALIGN ( _max_align ) ),
228 "_prefix is badly aligned" );
230 . = _text16_load_addr - _text16_link_addr;
231 _assert = ASSERT ( ( . == ALIGN ( _max_align ) ),
232 "_text16 is badly aligned" );
234 . = _data16_load_addr - _data16_link_addr;
235 _assert = ASSERT ( ( . == ALIGN ( _max_align ) ),
236 "_data16 is badly aligned" );
238 . = _textdata_load_addr - _textdata_link_addr;
239 _assert = ASSERT ( ( . == ALIGN ( _max_align ) ),
240 "_text is badly aligned" );
243 * Values calculated to save code from doing it
245 _text16_size_pgh = ( ( _text16_size + 15 ) / 16 );
246 _data16_size_pgh = ( ( _data16_size + 15 ) / 16 );
247 _load_size_pgh = ( ( _load_size + 15 ) / 16 );
248 _rom_size = ( ( _load_size + 511 ) / 512 );