• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* -*- sh -*- */
2
3/*
4 * Linker script for i386 images
5 *
6 */
7
8OUTPUT_FORMAT ( "elf32-i386", "elf32-i386", "elf32-i386" )
9OUTPUT_ARCH ( i386 )
10ENTRY ( _entry )
11
12SECTIONS {
13
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.
17     *
18     * The linker symbols _prefix_link_addr, load_addr, and
19     * _max_align may be specified explicitly.  If not specified, they
20     * will default to:
21     *
22     *   _prefix_link_addr	= 0
23     *   _load_addr		= 0
24     *   _max_align		= 16
25     *
26     * We guarantee alignment of virtual addresses to any alignment
27     * specified by the constituent object files (e.g. via
28     * __attribute__((aligned(x)))).  Load addresses are guaranteed
29     * only up to _max_align.  Provided that all loader and relocation
30     * code honours _max_align, this means that physical addresses are
31     * also guaranteed up to _max_align.
32     *
33     * Note that when using -DKEEP_IT_REAL, the UNDI segments are only
34     * guaranteed to be loaded on a paragraph boundary (i.e. 16-byte
35     * alignment).  Using _max_align>16 will therefore not guarantee
36     * >16-byte alignment of physical addresses when -DKEEP_IT_REAL is
37     * used (though virtual addresses will still be fully aligned).
38     *
39     */
40
41    /*
42     * The prefix
43     */
44
45    _prefix_link_addr = DEFINED ( _prefix_link_addr ) ? _prefix_link_addr : 0;
46    . = _prefix_link_addr;
47    _prefix = .;
48
49    .prefix : AT ( _prefix_load_offset + __prefix ) {
50	__prefix = .;
51	_entry = .;
52	*(.prefix)
53	*(.prefix.*)
54	_eprefix_progbits = .;
55    }
56
57    _eprefix = .;
58
59    /*
60     * The 16-bit sections
61     */
62
63    _text16_link_addr = 0;
64    . = _text16_link_addr;
65    _text16 = .;
66
67    . += 1;			/* Prevent NULL being valid */
68
69    .text16 : AT ( _text16_load_offset + __text16 ) {
70	__text16 = .;
71	*(.text.null_trap)
72	*(.text16)
73	*(.text16.*)
74	*(.text)
75	*(.text.*)
76	_etext16_progbits = .;
77    } = 0x9090
78
79    _etext16 = .;
80
81    _data16_link_addr = 0;
82    . = _data16_link_addr;
83    _data16 = .;
84
85    . += 1;			/* Prevent NULL being valid */
86
87    .rodata16 : AT ( _data16_load_offset + __rodata16 ) {
88	__rodata16 = .;
89	*(.rodata16)
90	*(.rodata16.*)
91	*(.rodata)
92	*(.rodata.*)
93    }
94    .data16 : AT ( _data16_load_offset + __data16 ) {
95	__data16 = .;
96	*(.data16)
97	*(.data16.*)
98	*(.data)
99	*(.data.*)
100	*(SORT(.tbl.*))		/* Various tables.  See include/tables.h */
101	_edata16_progbits = .;
102    }
103    .bss16 : AT ( _data16_load_offset + __bss16 ) {
104	__bss16 = .;
105	_bss16 = .;
106	*(.bss16)
107	*(.bss16.*)
108	*(.bss)
109	*(.bss.*)
110	*(COMMON)
111	_ebss16 = .;
112    }
113    .stack16 : AT ( _data16_load_offset + __stack16 ) {
114	__stack16 = .;
115	*(.stack16)
116	*(.stack16.*)
117	*(.stack)
118	*(.stack.*)
119    }
120
121    _edata16 = .;
122
123    _end = .;
124
125    /*
126     * Dispose of the comment and note sections to make the link map
127     * easier to read
128     */
129
130    /DISCARD/ : {
131	*(.comment)
132	*(.note)
133	*(.discard)
134    }
135
136    /*
137     * Load address calculations.  The slightly obscure nature of the
138     * calculations is because ALIGN(x) can only operate on the
139     * location counter.
140     */
141
142    _max_align		    = DEFINED ( _max_align ) ? _max_align : 16;
143    _load_addr		    = DEFINED ( _load_addr ) ? _load_addr : 0;
144
145    .			    = _load_addr;
146
147    .			   -= _prefix_link_addr;
148    _prefix_load_offset	    = ALIGN ( _max_align );
149    _prefix_load_addr	    = _prefix_link_addr + _prefix_load_offset;
150    _prefix_size	    = _eprefix - _prefix;
151    _prefix_progbits_size   = _eprefix_progbits - _prefix;
152    .			    = _prefix_load_addr + _prefix_progbits_size;
153
154    .			   -= _text16_link_addr;
155    _text16_load_offset	    = ALIGN ( _max_align );
156    _text16_load_addr	    = _text16_link_addr + _text16_load_offset;
157    _text16_size	    = _etext16 - _text16;
158    _text16_progbits_size   = _etext16_progbits - _text16;
159    .			    = _text16_load_addr + _text16_progbits_size;
160
161    .			   -= _data16_link_addr;
162    _data16_load_offset	    = ALIGN ( _max_align );
163    _data16_load_addr	    = _data16_link_addr + _data16_load_offset;
164    _data16_size	    = _edata16 - _data16;
165    _data16_progbits_size   = _edata16_progbits - _data16;
166    .			    = _data16_load_addr + _data16_progbits_size;
167
168    .			    = ALIGN ( _max_align );
169
170    _load_size		    = . - _load_addr;
171
172    /*
173     * Alignment checks.  ALIGN() can only operate on the location
174     * counter, so we set the location counter to each value we want
175     * to check.
176     */
177
178    . = _prefix_load_addr - _prefix_link_addr;
179    _assert = ASSERT ( ( . == ALIGN ( _max_align ) ),
180		       "_prefix is badly aligned" );
181
182    . = _text16_load_addr - _text16_link_addr;
183    _assert = ASSERT ( ( . == ALIGN ( _max_align ) ),
184		       "_text16 is badly aligned" );
185
186    . = _data16_load_addr - _data16_link_addr;
187    _assert = ASSERT ( ( . == ALIGN ( _max_align ) ),
188		       "_data16 is badly aligned" );
189
190    /*
191     * Values calculated to save code from doing it
192     */
193    _text16_size_pgh	= ( ( _text16_size + 15 ) / 16 );
194    _data16_size_pgh	= ( ( _data16_size + 15 ) / 16 );
195    _load_size_pgh	= ( ( _load_size + 15 ) / 16 );
196    _load_size_sect	= ( ( _load_size + 511 ) / 512 );
197}
198