在u-boot下,定義變量, linux
編譯,編譯完後 使用arm-linux-nm arm 沒有去頭的二進制可執行文件app
都在BSS段,均爲初始化。ide
打印以後會出算隨機值。ui
目前還處於uboot階段,若是在根文件系統的話,加載器把二進制可執行文件加載到內存,並將BSS段清零。 放在BSS段的變量所對應的空間,在二進制可執行文件中不佔空間。放在Data段才分配空間。this
ld --help spa
默認連接腳本:arm-linux-ld -verbosedebug
1 GNU ld (GNU Binutils) 2.20.1.20100303 2 Supported emulations: 3 armelf_linux_eabi 4 armelfb_linux_eabi 5 using internal linker script: 6 ================================================== 7 /* Script for -z combreloc: combine and sort reloc sections */ 8 OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", 9 "elf32-littlearm") //小端存儲的arm 10 OUTPUT_ARCH(arm) 11 ENTRY(_start) 12 SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib"); 13 SECTIONS 14 { 15 /* Read-only sections, merged into text segment: */ 16 PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x00008000)); . = SEGMENT_START("text-segment", 0x00008000) + SIZEOF_HEADERS; 17 .interp : { *(.interp) } 18 .note.gnu.build-id : { *(.note.gnu.build-id) } 19 .hash : { *(.hash) } 20 .gnu.hash : { *(.gnu.hash) } 21 .dynsym : { *(.dynsym) } 22 .dynstr : { *(.dynstr) } 23 .gnu.version : { *(.gnu.version) } 24 .gnu.version_d : { *(.gnu.version_d) } 25 .gnu.version_r : { *(.gnu.version_r) } 26 .rel.dyn : 27 { 28 *(.rel.init) 29 *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) 30 *(.rel.fini) 31 *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) 32 *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*) 33 *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) 34 *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) 35 *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) 36 *(.rel.ctors) 37 *(.rel.dtors) 38 *(.rel.got) 39 *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) 40 PROVIDE_HIDDEN (__rel_iplt_start = .); 41 *(.rel.iplt) 42 PROVIDE_HIDDEN (__rel_iplt_end = .); 43 PROVIDE_HIDDEN (__rela_iplt_start = .); 44 PROVIDE_HIDDEN (__rela_iplt_end = .); 45 } 46 .rela.dyn : 47 { 48 *(.rela.init) 49 *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) 50 *(.rela.fini) 51 *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) 52 *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) 53 *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) 54 *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) 55 *(.rela.ctors) 56 *(.rela.dtors) 57 *(.rela.got) 58 *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) 59 PROVIDE_HIDDEN (__rel_iplt_start = .); 60 PROVIDE_HIDDEN (__rel_iplt_end = .); 61 PROVIDE_HIDDEN (__rela_iplt_start = .); 62 *(.rela.iplt) 63 PROVIDE_HIDDEN (__rela_iplt_end = .); 64 } 65 .rel.plt : 66 { 67 *(.rel.plt) 68 } 69 .rela.plt : 70 { 71 *(.rela.plt) 72 } 73 .init : 74 { 75 KEEP (*(.init)) 76 } =0 77 .plt : { *(.plt) } 78 .iplt : { *(.iplt) } 79 .text : 80 { 81 *(.text.unlikely .text.*_unlikely) 82 *(.text .stub .text.* .gnu.linkonce.t.*) 83 /* .gnu.warning sections are handled specially by elf32.em. */ 84 *(.gnu.warning) 85 *(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx) 86 } =0 87 .fini : 88 { 89 KEEP (*(.fini)) 90 } =0 91 PROVIDE (__etext = .); 92 PROVIDE (_etext = .); 93 PROVIDE (etext = .); 94 .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } 95 .rodata1 : { *(.rodata1) } 96 .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } 97 __exidx_start = .; 98 .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } 99 __exidx_end = .; 100 .eh_frame_hdr : { *(.eh_frame_hdr) } 101 .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } 102 .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } 103 /* Adjust the address for the data segment. We want to adjust up to 104 the same address within the page on the next page up. */ 105 . = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); 106 /* Exception handling */ 107 .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } 108 .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } 109 /* Thread Local Storage sections */ 110 .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } 111 .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } 112 .preinit_array : 113 { 114 PROVIDE_HIDDEN (__preinit_array_start = .); 115 KEEP (*(.preinit_array)) 116 PROVIDE_HIDDEN (__preinit_array_end = .); 117 } 118 .init_array : 119 { 120 PROVIDE_HIDDEN (__init_array_start = .); 121 KEEP (*(SORT(.init_array.*))) 122 KEEP (*(.init_array)) 123 PROVIDE_HIDDEN (__init_array_end = .); 124 } 125 .fini_array : 126 { 127 PROVIDE_HIDDEN (__fini_array_start = .); 128 KEEP (*(.fini_array)) 129 KEEP (*(SORT(.fini_array.*))) 130 PROVIDE_HIDDEN (__fini_array_end = .); 131 } 132 .ctors : 133 { 134 /* gcc uses crtbegin.o to find the start of 135 the constructors, so we make sure it is 136 first. Because this is a wildcard, it 137 doesn't matter if the user does not 138 actually link against crtbegin.o; the 139 linker won't look for a file to match a 140 wildcard. The wildcard also means that it 141 doesn't matter which directory crtbegin.o 142 is in. */ 143 KEEP (*crtbegin.o(.ctors)) 144 KEEP (*crtbegin?.o(.ctors)) 145 /* We don't want to include the .ctor section from 146 the crtend.o file until after the sorted ctors. 147 The .ctor section from the crtend file contains the 148 end of ctors marker and it must be last */ 149 KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) 150 KEEP (*(SORT(.ctors.*))) 151 KEEP (*(.ctors)) 152 } 153 .dtors : 154 { 155 KEEP (*crtbegin.o(.dtors)) 156 KEEP (*crtbegin?.o(.dtors)) 157 KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) 158 KEEP (*(SORT(.dtors.*))) 159 KEEP (*(.dtors)) 160 } 161 .jcr : { KEEP (*(.jcr)) } 162 .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) } 163 .dynamic : { *(.dynamic) } 164 . = DATA_SEGMENT_RELRO_END (0, .); 165 .got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) } 166 .data : 167 { 168 PROVIDE (__data_start = .); 169 *(.data .data.* .gnu.linkonce.d.*) 170 SORT(CONSTRUCTORS) 171 } 172 .data1 : { *(.data1) } 173 _edata = .; PROVIDE (edata = .); 174 __bss_start = .; 175 __bss_start__ = .; 176 .bss : //找到了 177 { 178 *(.dynbss) 179 *(.bss .bss.* .gnu.linkonce.b.*) 180 *(COMMON) 181 /* Align here to ensure that the .bss section occupies space up to 182 _end. Align after .bss to ensure correct alignment even if the 183 .bss section disappears because there are no input sections. 184 FIXME: Why do we need it? When there is no .bss section, we don't 185 pad the .data section. */ 186 . = ALIGN(. != 0 ? 32 / 8 : 1); 187 } 188 _bss_end__ = . ; __bss_end__ = . ; 189 . = ALIGN(32 / 8); 190 . = ALIGN(32 / 8); 191 __end__ = . ; 192 _end = .; PROVIDE (end = .); 193 . = DATA_SEGMENT_END (.); 194 /* Stabs debugging sections. */ 195 .stab 0 : { *(.stab) } 196 .stabstr 0 : { *(.stabstr) } 197 .stab.excl 0 : { *(.stab.excl) } 198 .stab.exclstr 0 : { *(.stab.exclstr) } 199 .stab.index 0 : { *(.stab.index) } 200 .stab.indexstr 0 : { *(.stab.indexstr) } 201 .comment 0 : { *(.comment) } 202 /* DWARF debug sections. 203 Symbols in the DWARF debugging sections are relative to the beginning 204 of the section so we begin them at 0. */ 205 /* DWARF 1 */ 206 .debug 0 : { *(.debug) } 207 .line 0 : { *(.line) } 208 /* GNU DWARF 1 extensions */ 209 .debug_srcinfo 0 : { *(.debug_srcinfo) } 210 .debug_sfnames 0 : { *(.debug_sfnames) } 211 /* DWARF 1.1 and DWARF 2 */ 212 .debug_aranges 0 : { *(.debug_aranges) } 213 .debug_pubnames 0 : { *(.debug_pubnames) } 214 /* DWARF 2 */ 215 .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } 216 .debug_abbrev 0 : { *(.debug_abbrev) } 217 .debug_line 0 : { *(.debug_line) } 218 .debug_frame 0 : { *(.debug_frame) } 219 .debug_str 0 : { *(.debug_str) } 220 .debug_loc 0 : { *(.debug_loc) } 221 .debug_macinfo 0 : { *(.debug_macinfo) } 222 /* SGI/MIPS DWARF 2 extensions */ 223 .debug_weaknames 0 : { *(.debug_weaknames) } 224 .debug_funcnames 0 : { *(.debug_funcnames) } 225 .debug_typenames 0 : { *(.debug_typenames) } 226 .debug_varnames 0 : { *(.debug_varnames) } 227 /* DWARF 3 */ 228 .debug_pubtypes 0 : { *(.debug_pubtypes) } 229 .debug_ranges 0 : { *(.debug_ranges) } 230 .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) } 231 .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } 232 /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) } 233 } 234 235 236 ==================================================
如今不使用默認的BSS段,使用本身寫的BSS段。code
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") OUTPUT_ARCH(arm) ENTRY(_start) SECTIONS { . = 0x50000000; .text : { start.o *(.text) } . = ALIGN(4); laomi_data_start = .; .laomi : { *(.laomi) } laomi_data_end = .; .data : { *(.data) } . = ALIGN(4); _bss_start = .; .bss : { *(.bss) } . = ALIGN(4); _bss_end = .; }
1 #include <led.h> 2 #include <key.h> 3 #include <lib.h> 4 #include <uart.h> 5 #include <backlight.h> 6 #include <lcd.h> 7 #include <mmu.h> 8 9 u32 *T = (void *)0x60000000; 10 11 int var0; 12 int var1 = 0; 13 14 int data = 9527; 15 16 int glb0 __attribute__ ((unused, section(".jason")))= 7788; 17 int glb1 __attribute__ ((unused, section(".jason")))= 8877; 18 int glb2 __attribute__ ((unused, section(".jason")))= 8866; 19 int glb3 __attribute__ ((unused, section(".jason")))= 8899; 20 21 extern int jason_data_start; 22 extern int jason_data_end; 23 24 void entry(void) 25 { 26 int *p = &jason_data_start; 27 28 while (p < &jason_data_end) { 29 printf("*p = %d\n", *p); 30 p++; 31 } 32 }
1 .PHONE:clean 2 3 TARGET := arm 4 BIN := $(TARGET).bin 5 LDADD := 0x50000000 6 ASM := start.o 7 OBJS := entry.o lib.o mmu.o 8 CROSS_COMPILE := arm-linux- 9 CC := $(CROSS_COMPILE)gcc 10 LD := $(CROSS_COMPILE)ld 11 OBJCOPY := $(CROSS_COMPILE)objcopy 12 NM := $(CROSS_COMPILE)nm 13 OBJDUMP := $(CROSS_COMPILE)objdump 14 15 all:$(TARGET) 16 $(OBJCOPY) -O binary $< $(BIN) 17 $(TARGET):$(ASM) $(OBJS) 18 $(LD) $(ASM) $(OBJS) -Tld.lds -o $@ 19 20 %.o:%.S 21 $(CC) -c $^ 22 %.o:%.c 23 $(CC) -c $^ -Iinclude -Wall -fno-builtin 24 25 clean: 26 rm -f *.o $(BIN) $(TARGET) 27 28 29
而且指定連接腳本,拿到結果blog