Reference article: https://sourceware.org/ml/binutils/2007-07/msg00154.html
in link scripts, often have this code:
SECTIONS
{
.....
. = ALIGN(4);
.rodata : { *(.rodata) }
. = ALIGN(4);
.data : { *(.data) }
. = ALIGN(4);
.got : { *(.got) }
. = ALIGN(4);
__bss_start = .;
.bss : { *(.bss) }
_end = .;
}
Wherein __bss_start, _end BSS segment represents the start, end address.
When we want to clear this space,
1. In assembly code can be directly referenced __bss_start, _end, such as:
ldr r0, =__bss_start
ldr r1, =_end
2. In the C code, we can not use them directly, do this:
void clean_bss(void)
{
extern int __bss_start, _end;
int *p = &__bss_start;
for (; p < &_end; p++)
*p = 0;
}
__bss_start, _end not represent a value it? In C code Why use the address ampersand (&)?
Cause:
A
C code, this statement:
int foo = 1000;
It leads to two things happen:
1. In the code, leaving 4 bytes of space, storage number 1000
2 In symbole talbe C language, i.e., the symbol table, there is a named foo items inside it there was a 4-byte address space.
We performed foo = 1, the Address foo corresponding to go to the symbol table and the value 1 filled to the address of the corresponding memory;
we perform address int * a = & during foo, will direct the symbol table of foo, wrote a.
two.
In the linker script, it is assumed
__bss_start = 1000
__bss_start is not a variable, it's just a value, do not need to leave some space in memory to save it;
in the C language, there will be a symbol table entry named __bss_start, this project value (address value) 1000;
note that the 1000 does not actually exist memory.
three.
So: In the C language, go to the link using the values defined in the script, you should do this:
extern int __bss_start;
int val = &__bss_start;
Use the address value to get it & notation in the symbol table.
Note that this value is only linked value defined in the script, does not mean that the address of a variable.