Towards making KEEP_IT_REAL work again.
[gpxe.git] / src / arch / i386 / scripts / i386-kir.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      * 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     .text16 : AT ( _text16_load_offset + __text16 ) {
68         __text16 = .;
69         *(.text.null_trap)
70         *(.text16)
71         *(.text16.*)
72         *(.text)
73         *(.text.*)
74         _etext16_progbits = .;
75     } = 0x9090
76
77     _etext16 = .;
78
79     _data16_link_addr = 0;
80     . = _data16_link_addr;
81     _data16 = .;
82
83     .rodata16 : AT ( _data16_load_offset + __rodata16 ) {
84         __rodata16 = .;
85         *(.rodata16)
86         *(.rodata16.*)
87         *(.rodata)
88         *(.rodata.*)
89     }
90     .data16 : AT ( _data16_load_offset + __data16 ) {
91         __data16 = .;
92         *(.data16)
93         *(.data16.*)
94         *(.data)
95         *(.data.*)
96         *(SORT(.tbl.*))         /* Various tables.  See include/tables.h */
97         _edata16_progbits = .;
98     }
99     .bss16 : AT ( _data16_load_offset + __bss16 ) {
100         __bss16 = .;
101         _bss16 = .;
102         *(.bss16)
103         *(.bss16.*)
104         *(.bss)
105         *(.bss.*)
106         *(COMMON)
107         _ebss16 = .;
108     }
109     .stack16 : AT ( _data16_load_offset + __stack16 ) {
110         __stack16 = .;
111         *(.stack16)
112         *(.stack16.*)
113         *(.stack)
114         *(.stack.*)
115     }
116
117     _edata16 = .;
118
119     _end = .;
120
121     /*
122      * Dispose of the comment and note sections to make the link map
123      * easier to read
124      */
125
126     /DISCARD/ : {
127         *(.comment)
128         *(.note)
129     }
130
131     /*
132      * Load address calculations.  The slightly obscure nature of the
133      * calculations is because ALIGN(x) can only operate on the
134      * location counter.
135      */
136
137     _max_align              = DEFINED ( _max_align ) ? _max_align : 16;
138     _load_addr              = DEFINED ( _load_addr ) ? _load_addr : 0;
139
140     .                       = _load_addr;
141
142     .                      -= _prefix_link_addr;
143     _prefix_load_offset     = ALIGN ( _max_align );
144     _prefix_load_addr       = _prefix_link_addr + _prefix_load_offset;
145     _prefix_size            = _eprefix - _prefix;
146     _prefix_progbits_size   = _eprefix_progbits - _prefix;
147     .                       = _prefix_load_addr + _prefix_progbits_size;
148
149     .                      -= _text16_link_addr;
150     _text16_load_offset     = ALIGN ( _max_align );
151     _text16_load_addr       = _text16_link_addr + _text16_load_offset;
152     _text16_size            = _etext16 - _text16;
153     _text16_progbits_size   = _etext16_progbits - _text16;
154     .                       = _text16_load_addr + _text16_progbits_size;
155
156     .                      -= _data16_link_addr;
157     _data16_load_offset     = ALIGN ( _max_align );
158     _data16_load_addr       = _data16_link_addr + _data16_load_offset;
159     _data16_size            = _edata16 - _data16;
160     _data16_progbits_size   = _edata16_progbits - _data16;
161     .                       = _data16_load_addr + _data16_progbits_size;
162
163     .                       = ALIGN ( _max_align );
164
165     _load_size              = . - _load_addr;
166
167     /*
168      * Alignment checks.  ALIGN() can only operate on the location
169      * counter, so we set the location counter to each value we want
170      * to check.
171      */
172
173     . = _prefix_load_addr - _prefix_link_addr;
174     _assert = ASSERT ( ( . == ALIGN ( _max_align ) ),
175                        "_prefix is badly aligned" );
176
177     . = _text16_load_addr - _text16_link_addr;
178     _assert = ASSERT ( ( . == ALIGN ( _max_align ) ),
179                        "_text16 is badly aligned" );
180
181     . = _data16_load_addr - _data16_link_addr;
182     _assert = ASSERT ( ( . == ALIGN ( _max_align ) ),
183                        "_data16 is badly aligned" );
184
185     /*
186      * Values calculated to save code from doing it
187      */
188     _text16_size_pgh    = ( ( _text16_size + 15 ) / 16 );
189     _data16_size_pgh    = ( ( _data16_size + 15 ) / 16 );
190     _load_size_pgh      = ( ( _load_size + 15 ) / 16 );
191     _rom_size           = ( ( _load_size + 511 ) / 512 );
192 }