I am trying to build a sample bare-metal ARM project using "arm-none-eabi-" tool chain.
Makefile
CC := arm-none-eabi-gcc
LD := arm-none-eabi-ld
AS := arm-none-eabi-as
AR := arm-none-eabi-ar -cr
OBJCOPY := arm-none-eabi-objcopy
CFLAGS := -mcpu=arm7tdmi-s -g3
AS_FLAGS := -mcpu=arm7tdmi-s -g3
LD_FLAGS := -loslayer
LD_DIR := -Llib
LD_SCRIPT := lpc2138.ld
LIB_DIR := lib
TARGET := image.hex
OBJS := main.o startup.o
$(TARGET) : $(TARGET:%.hex=%)
$(OBJCOPY) -O ihex $< $@
$(TARGET:%.hex=%) : $(OBJS) liboslayer.a
$(LD) -o $@ $(LD_DIR) -T $(LD_SCRIPT) $(OBJS) $(LD_FLAGS)
liboslayer.a : oslayer.o
$(AR) lib/$@ $^
startup.o : startup.s
$(AS) $(AS_FLAGS) -o $@ $<
%.o : %.c
$(CC) -c $(CFLAGS) -o $@ $<
clean :
rm -rf $(TARGET) $(TARGET:%.hex=%) *.o $(LIB_DIR)/*.a
main.c
int a[]= {1,2};
int b[5];
int main()
{
int i,sum=0;
for(i = 0; i < 50; i++)
{
sum+=i;
b[0] = a[1];
a[1]++;
b[3]--;
}
return 0;
}
lpc2138.ld (Linker script)
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 512K
SRAM (rw) : ORIGIN = 0x40000000, LENGTH = 32K
}
SECTIONS
{
.text :
{
startup.o (.text)
*(.text)
. = ALIGN(4);
} > FLASH
.rodata :
{
*(.rodata)
. = ALIGN(4);
} > FLASH
.data :
{
__data_load__ = LOADADDR (.data);
__data_start__ = .;
*(.data)
. = ALIGN(4);
__data_end__ = .;
} > SRAM AT > FLASH
.bss :
{
__bss_start__ = .;
*(.bss)
. = ALIGN(4);
__bss_end__ = .;
} > SRAM
.stack :
{
__stack_start__ = .;
. = . + (LENGTH(SRAM) - SIZEOF(.data) - SIZEOF(.bss)) / 2;
. = ALIGN(4);
__stack_end__ = .;
} > SRAM
.heap :
{
__heap_start__ = .;
. += LENGTH(SRAM) - SIZEOF(.data) - SIZEOF(.bss) - SIZEOF(.stack);
. = ALIGN(4);
__heap_end__ = .;
} > SRAM
}
After a successful build I just ran arm-none-eabi-nm image
. The output is shown below.
40000000 D a
40000008 B b
40000008 B __bss_end__
40000008 B __bss_start__
40000008 D __data_end__
000000b8 A __data_load__
40000000 D __data_start__
40008000 B __heap_end__
40004010 B __heap_start__
0000001c T main
40004010 B __stack_end__
4000001c B __stack_start__
00000000 T _start
My question is why __bss_start__
and __bss_end__
refer to the same address even though there is an uninitialised global variable in my c source code?
I observed that the uninitialized global variables belong to a section called COMMON in the object file not in BSS. I modified my linker script as follows(Just added "*(COMMON)" in the .bss section)
Now the result is like the following