blob: c8bd297e51946736fd151da705376cc2a4ff004f [file] [log] [blame]
Aaron Durbinad935522012-12-24 14:28:37 -06001OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
2OUTPUT_ARCH(i386)
3
4/*
5 * This linker script is used to link rmodules (relocatable modules). It
6 * links at zero so that relocation fixups are easy when placing the binaries
7 * anywhere in the address space.
8 *
9 * NOTE: The program's loadable sections (text, module_params, and data) are
10 * packed into the flat blob using the AT directive. The rmodule loader assumes
11 * the entire program resides in one contiguous address space. Therefore,
12 * alignment for a given section (if required) needs to be done at the end of
13 * the preceeding section. e.g. if the data section should be aligned to an 8
14 * byte address the text section should have ALIGN(8) at the end of its section.
15 * Otherwise there won't be a consistent mapping between the flat blob and the
16 * loaded program.
17 */
18
19BASE_ADDRESS = 0x00000;
20
21SECTIONS
22{
23 . = BASE_ADDRESS;
24
25 .header : AT (0) {
26 *(.module_header);
27 . = ALIGN(8);
28 }
29
30 /* Align the start of the module program to a large enough alignment
31 * so that any data in the program with an alignement property is met.
32 * Essentially, this alignment is the maximum possible data alignment
33 * property a program can have. */
34 . = ALIGN(4096);
35 _module_link_start_addr = .;
36 _payload_begin_offset = LOADADDR(.header) + SIZEOF(.header);
37
38 .text : AT (_payload_begin_offset) {
39 /* C code of the module. */
40 *(.text);
41 *(.text.*);
42 /* C read-only data. */
43 . = ALIGN(16);
Aaron Durbinf7c6d482013-02-06 15:47:31 -060044
45 /* The driver sections are to allow linking coreboot's
46 * ramstage with the rmodule linker. Any changes made in
47 * coreboot_ram.ld should be made here as well. */
48 console_drivers = .;
49 *(.rodata.console_drivers)
50 econsole_drivers = . ;
51 . = ALIGN(4);
52 pci_drivers = . ;
53 *(.rodata.pci_driver)
54 epci_drivers = . ;
55 cpu_drivers = . ;
56 *(.rodata.cpu_driver)
57 ecpu_drivers = . ;
58 . = ALIGN(4);
59
Aaron Durbinad935522012-12-24 14:28:37 -060060 *(.rodata);
61 *(.rodata.*);
62 . = ALIGN(4);
63 }
64
65 .module_params : AT (LOADADDR(.text) + SIZEOF(.text)) {
66 /* The parameters section can be used to pass parameters
67 * to a module, however there has to be an prior agreement
68 * on how to interpret the parameters. */
69 _module_params_begin = .;
70 *(.module_parameters);
71 _module_params_end = .;
72 . = ALIGN(4);
73 }
74
75 .data : AT (LOADADDR(.module_params) + SIZEOF(.module_params)) {
76 _sdata = .;
77 *(.data);
78 . = ALIGN(4);
79 _edata = .;
80 }
81
82 /* _payload_end marks the end of the module's code and data. */
83 _payload_end_offset = LOADADDR(.data) + SIZEOF(.data);
84
85 .bss (NOLOAD) : {
Aaron Durbinf7c6d482013-02-06 15:47:31 -060086 /* C uninitialized data of the module. */
87 _bss = .;
Aaron Durbinad935522012-12-24 14:28:37 -060088 *(.bss);
89 *(.sbss);
90 *(COMMON);
91 . = ALIGN(8);
Aaron Durbinf7c6d482013-02-06 15:47:31 -060092 _ebss = .;
Aaron Durbinad935522012-12-24 14:28:37 -060093
Aaron Durbinad935522012-12-24 14:28:37 -060094 /*
95 * Place the heap after BSS. The heap size is passed in by
96 * by way of ld --defsym=__heap_size=<>
97 */
98 _heap = .;
99 . = . + __heap_size;
100 _eheap = .;
101 }
102
103 /* _module_program_size is the total memory used by the program. */
104 _module_program_size = _eheap - _module_link_start_addr;
105
Aaron Durbinf7c6d482013-02-06 15:47:31 -0600106 /* coreboot's ramstage uses the _ram_seg and _eram_seg symbols
107 * for determining its load location. Provide those to help it out.
108 * It's a nop for any non-ramstage rmodule. */
109 _ram_seg = _module_link_start_addr;
110 _eram_seg = _module_link_start_addr + _module_program_size;
111
Aaron Durbinad935522012-12-24 14:28:37 -0600112 /* The relocation information is linked on top of the BSS section
113 * because the BSS section takes no space on disk. The relocation data
114 * resides directly after the data section in the flat binary. */
115 .relocations ADDR(.bss) : AT (_payload_end_offset) {
116 *(.rel.*);
117 }
118 _relocations_begin_offset = LOADADDR(.relocations);
119 _relocations_end_offset = _relocations_begin_offset +
120 SIZEOF(.relocations);
121
122 /DISCARD/ : {
123 /* Drop unnecessary sections. Since these modules are linked
124 * as shared objects there are dynamic sections. These sections
125 * aren't needed so drop them. */
126 *(.comment);
127 *(.note);
128 *(.note.*);
129 *(.dynamic);
130 *(.dynsym);
131 *(.dynstr);
132 *(.gnu.hash);
133 *(.eh_frame);
134 }
135}