GCC链接器BSS段起止符号长度为零的异常问题
Alright, let's dig into this BSS segment issue you're facing. I've run into similar headaches when tweaking custom linker scripts for embedded targets, so I think I can help you sort this out.
What's Going Wrong Here
First off, the core problem is that your linker script isn't properly defining the __bss_start__ and __bss_end__ symbols to map to the actual start and end of your .bss segment. Even though objdump shows your timer_delayCount variable is correctly placed at 0x20000000 (with 4 bytes of space), the symbols you're using to trigger the BSS clear are stuck at the same address—making your code think there's nothing to zero out.
How to Fix the Linker Script
The fix almost always comes down to how you define those BSS symbols in your linker script. Here's the correct pattern to follow:
/* First, make sure your RAM region is properly defined (example below) */ MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 128K } /* Then define the .bss section with correct symbol placement */ SECTIONS { /* ... other sections like .text, .data go here ... */ .bss : { __bss_start__ = .; /* Bind start symbol to current address */ *(.bss*) /* Include all .bss sections from object files */ *(COMMON) /* Include common symbols (also part of BSS) */ __bss_end__ = .; /* Bind end symbol to address after BSS content */ } > RAM /* Ensure this section is placed in your RAM region */ }
Common Mistakes That Cause This Issue
If your current script doesn't follow this structure, here are the most likely culprits:
- Symbols defined outside the .bss section: If you set
__bss_start__and__bss_end__before/after the.bss : { ... }block, the linker might not update the symbol values to match the actual .bss placement. - Missing
*(COMMON): Some compilers put uninitialized global variables inCOMMONsections instead of.bss—omitting this can leave parts of your BSS unaccounted for. - Typos in symbol names: Double-check that your code uses the exact same symbol names as your linker script (e.g.,
__bss_start__vs.__bss_start—missing underscores are easy to miss!).
Verify the Fix
After updating your linker script:
- Use the
nmcommand to check the symbol values directly:
You should seenm your_project.elf | grep bss__bss_start__at0x20000000and__bss_end__at0x20000004(matching yourtimer_delayCountsize). - Debug your BSS clear function again—this time the check
__bss_start__ != __bss_end__should pass, and the memset will run as expected.
Why the LED Still Blinked (For Now)
You got lucky here: the RAM address 0x20000000 probably had a value that worked for your timer delay logic when the board powered on. But this is totally unreliable—on a different power cycle or board, that uninitialized value could be garbage, breaking your code.
内容的提问来源于stack exchange,提问作者Chris

