[pxe] Add a dummy PXENV+ entry point at UNDI_CS:0000
[people/cooldavid/gpxe.git] / src / arch / i386 / scripts / i386.lds
1 /* -*- sh -*- */
2
3 /*
4  * Linker script for i386 images
5  *
6  */
7
8 OUTPUT_FORMAT ( "elf32-i386", "elf32-i386", "elf32-i386" )
9 OUTPUT_ARCH ( i386 )
10 ENTRY ( _entry )
11
12 SECTIONS {
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      * We guarantee alignment of virtual addresses to any alignment
19      * specified by the constituent object files (e.g. via
20      * __attribute__((aligned(x)))).  Load addresses are guaranteed
21      * only up to _max_align.  Provided that all loader and relocation
22      * code honours _max_align, this means that physical addresses are
23      * also guaranteed up to _max_align.
24      *
25      * Note that when using -DKEEP_IT_REAL, the UNDI segments are only
26      * guaranteed to be loaded on a paragraph boundary (i.e. 16-byte
27      * alignment).  Using _max_align>16 will therefore not guarantee
28      * >16-byte alignment of physical addresses when -DKEEP_IT_REAL is
29      * used (though virtual addresses will still be fully aligned).
30      *
31      */
32
33     /*
34      * Weak symbols that need zero values if not otherwise defined
35      */
36
37     . = 0;
38     .weak : AT ( 0 ) {
39         *(.weak)
40     }
41     _assert = ASSERT ( ( . == 0 ), ".weak is non-zero length" );
42
43     /*
44      * The prefix
45      */
46
47     _prefix_link_addr = 0;
48     . = _prefix_link_addr;
49     _prefix = .;
50
51     .prefix : AT ( _prefix_load_offset + __prefix ) {
52         __prefix = .;
53         _entry = .;
54         *(.prefix)
55         *(.prefix.*)
56         _eprefix_progbits = .;
57     }
58     
59     _eprefix = .;
60
61     /*
62      * The 16-bit sections, if present
63      */
64
65     _text16_link_addr = 0;
66     . = _text16_link_addr;
67     _text16 = .;
68
69     /* We need to allow code at the NULL address in .text16 */
70
71     .text16 : AT ( _text16_load_offset + __text16 ) {
72         __text16 = .;
73         *(.text16.null)
74         . += 1;                 /* Prevent NULL being valid */
75         *(.text16)
76         *(.text16.*)
77         _etext16_progbits = .;
78     } = 0x9090
79
80     _etext16 = .;
81
82     _data16_link_addr = 0;
83     . = _data16_link_addr;
84     _data16 = .;
85
86     . += 1;                     /* Prevent NULL being valid */
87
88     .rodata16 : AT ( _data16_load_offset + __rodata16 ) {
89         __rodata16 = .;
90         *(.rodata16)
91         *(.rodata16.*)
92     }
93     .data16 : AT ( _data16_load_offset + __data16 ) {
94         __data16 = .;
95         *(.data16)
96         *(.data16.*)
97         _edata16_progbits = .;
98     }
99     .bss16 : AT ( _data16_load_offset + __bss16 ) {
100         __bss16 = .;
101         _bss16 = .;
102         *(.bss16)
103         *(.bss16.*)
104         _ebss16 = .;
105     }
106     .stack16 : AT ( _data16_load_offset + __stack16 ) {
107         __stack16 = .;
108         *(.stack16)
109         *(.stack16.*)
110     }
111
112     _edata16 = .;
113
114     /*
115      * The 32-bit sections
116      */
117
118     _textdata_link_addr = 0;
119     . = _textdata_link_addr;
120     _textdata = .;
121
122     _text = .;
123
124     . += 1;                     /* Prevent NULL being valid */
125
126     .text : AT ( _textdata_load_offset + __text ) {
127         __text = .;
128         *(.text.null_trap)
129         *(.text)
130         *(.text.*)
131     } = 0x9090
132
133     _etext = .;
134
135     _data = .;
136
137     .rodata : AT ( _textdata_load_offset + __rodata ) {
138         __rodata = .;
139         *(.rodata)
140         *(.rodata.*)
141     }
142     .data : AT ( _textdata_load_offset + __data ) {
143         __data = .;
144         *(.data)
145         *(.data.*)
146         *(SORT(.tbl.*))         /* Various tables.  See include/tables.h */
147         _etextdata_progbits = .;
148     }
149     .bss : AT ( _textdata_load_offset + __bss ) {
150         __bss = .;
151         _bss = .;
152         *(.bss)
153         *(.bss.*)
154         *(COMMON)
155         _ebss = .;
156     }
157     .stack : AT ( _textdata_load_offset + __stack ) {
158         __stack = .;
159         *(.stack)
160         *(.stack.*)
161     }
162
163     _edata = .;
164
165     _etextdata = .;
166
167     _end = .;
168
169     /*
170      * Compressor information block
171      */
172
173     _zinfo_link_addr = 0;
174     . = _zinfo_link_addr;
175     _zinfo = .;
176
177     .zinfo : AT ( _zinfo_load_offset + __zinfo ) {
178         __zinfo = .;
179         _entry = .;
180         *(.zinfo)
181         *(.zinfo.*)
182         _ezinfo_progbits = .;
183     }
184     
185     _ezinfo = .;
186
187     /*
188      * Dispose of the comment and note sections to make the link map
189      * easier to read
190      */
191
192     /DISCARD/ : {
193         *(.comment)
194         *(.note)
195     }
196
197     /*
198      * Load address calculations.  The slightly obscure nature of the
199      * calculations is because ALIGN(x) can only operate on the
200      * location counter.
201      */
202
203     _max_align              = 16;
204     _load_addr              = 0;
205
206     .                       = _load_addr;
207
208     .                      -= _prefix_link_addr;
209     _prefix_load_offset     = ALIGN ( _max_align );
210     _prefix_load_addr       = _prefix_link_addr + _prefix_load_offset;
211     _prefix_size            = _eprefix - _prefix;
212     _prefix_progbits_size   = _eprefix_progbits - _prefix;
213     .                       = _prefix_load_addr + _prefix_progbits_size;
214
215     .                      -= _text16_link_addr;
216     _text16_load_offset     = ALIGN ( _max_align );
217     _text16_load_addr       = _text16_link_addr + _text16_load_offset;
218     _text16_size            = _etext16 - _text16;
219     _text16_progbits_size   = _etext16_progbits - _text16;
220     .                       = _text16_load_addr + _text16_progbits_size;
221
222     .                      -= _data16_link_addr;
223     _data16_load_offset     = ALIGN ( _max_align );
224     _data16_load_addr       = _data16_link_addr + _data16_load_offset;
225     _data16_size            = _edata16 - _data16;
226     _data16_progbits_size   = _edata16_progbits - _data16;
227     .                       = _data16_load_addr + _data16_progbits_size;
228
229     .                      -= _textdata_link_addr;
230     _textdata_load_offset   = ALIGN ( _max_align );
231     _textdata_load_addr     = _textdata_link_addr + _textdata_load_offset;
232     _textdata_size          = _etextdata - _textdata;
233     _textdata_progbits_size = _etextdata_progbits - _textdata;
234     .                       = _textdata_load_addr + _textdata_progbits_size;
235
236     _load_size              = . - _load_addr;
237
238     .                      -= _zinfo_link_addr;
239     _zinfo_load_offset      = ALIGN ( _max_align );
240     _zinfo_load_addr        = _zinfo_link_addr + _zinfo_load_offset;
241     _zinfo_size             = _ezinfo - _zinfo;
242     _zinfo_progbits_size    = _ezinfo_progbits - _zinfo;
243     .                       = _zinfo_load_addr + _zinfo_progbits_size;
244
245     _payload_offset         = _text16_load_offset;
246
247     /*
248      * Alignment checks.  ALIGN() can only operate on the location
249      * counter, so we set the location counter to each value we want
250      * to check.
251      */
252
253     . = _prefix_load_addr - _prefix_link_addr;
254     _assert = ASSERT ( ( . == ALIGN ( _max_align ) ),
255                        "_prefix is badly aligned" );
256
257     . = _text16_load_addr - _text16_link_addr;
258     _assert = ASSERT ( ( . == ALIGN ( _max_align ) ),
259                        "_text16 is badly aligned" );
260
261     . = _data16_load_addr - _data16_link_addr;
262     _assert = ASSERT ( ( . == ALIGN ( _max_align ) ),
263                        "_data16 is badly aligned" );
264
265     . = _textdata_load_addr - _textdata_link_addr;
266     _assert = ASSERT ( ( . == ALIGN ( _max_align ) ),
267                        "_text is badly aligned" );
268
269     /*
270      * Values calculated to save code from doing it
271      */
272     _prefix_size_pgh    = ( ( _prefix_size + 15 ) / 16 );
273     _prefix_size_sect   = ( ( _prefix_size + 511 ) / 512 );
274     _text16_size_pgh    = ( ( _text16_size + 15 ) / 16 );
275     _data16_size_pgh    = ( ( _data16_size + 15 ) / 16 );
276
277     /*
278      * Load sizes in paragraphs and sectors.  Note that wherever the
279      * _load_size variables are used, there must be a corresponding
280      * .zinfo.fixup section.
281      */
282     _load_size_pgh      = ( ( _load_size + 15 ) / 16 );
283     _load_size_sect     = ( ( _load_size + 511 ) / 512 );
284 }