5.5.16 · D5 · HinglishEmbedded Systems & Real-Time Software

Question bankStartup code — vector table, reset handler, stack initialization

2,050 words9 min read↑ Read in English

5.5.16 · D5 · Coding › Embedded Systems & Real-Time Software › Startup code — vector table, reset handler, stack initializa

Shuru karne se pehle, teen plain-word reminders taaki neeche koi bhi term unexplained na rahe:


Sach ya jhooth — justify karo

Cortex-M vector table ki har entry ek function pointer hai jis par CPU jump kar sakta hai.
False — entry 0 initial stack-top value hai, ek plain 32-bit number jise hardware MSP mein load karta hai. C mein iska function-pointer type sirf isliye hai taaki array uniform rahe; hardware kabhi iske paas jump nahi karta.
Reset handler ko main() se pehle run karna zaroori hai kyunki C standard ek aisa environment assume karta hai jo main() khud apne liye nahi bana sakta.
True — int g=42; assume karta hai ki g mein pehle se 42 hai aur int z; assume karta hai ki z 0 hai, lekin main ke apne code mein kuch bhi .data copy nahi karta ya .bss clear nahi karta; woh kaam pehle se complete hona chahiye jab main start ho.
Ek full-descending stack par, koi value push karte waqt pehle value likhi jaati hai, phir stack pointer decrement hota hai.
False — full-descending ka matlab hai pehle decrement, phir write. SP last used slot ko point karta hai, isliye ek naya slot banane ke liye store karne se pehle SP ko neeche move karna padta hai (dekho Stack vs Heap memory layout).
_estack RAM ka lowest address hota hai.
False — _estack highest RAM address + 1 (end) hota hai, kyunki ek descending stack upar se start hota hai aur heap ki taraf neeche grow karta hai.
Agar tum .bss zero kar do lekin .data copy karna bhool jao, toh program phir bhi sahi behave karta hai.
False — int g=42; jaise initialized globals Flash-time garbage read karenge (power-up par RAM mein jo kuch bhi tha), kyunki kisi ne bhi 42 unke RAM slot mein nahi daala.
.bss variables ke liye Flash image mein zeros store karna harmless hoga, bas thoda wasteful.
Mostly true lekin baat waste ki hai: yeh binary ko zeros ke runs se bloat karta hai aur Flash programming ko lamba karta hai; isliye hi .bss ko "clear at runtime" define kiya gaya hai na ki "load from Flash."
Vector table sirf address 0x00000000 par hi reh sakta hai.
False — reset ke baad ek bootloader VTOR (Vector Table Offset Register) set kar sakta hai taaki table kahin aur point kare, jaise Flash mein kisi application region mein upar.
Agar main() return kare, toh execution cleanly ruk jaata hai.
False — wapas jaane ke liye koi OS nahi hai, isliye main se return karna undefined memory mein chala jaata hai. Reset handler while(1){} ke saath khatam hota hai taaki us case ko deliberately trap kiya ja sake.

Error dhundho

void (*vt[])(void) = { Reset_Handler, &_estack, ... }; — is ordering mein kya galat hai?
Dono entries swap hain: word 0 mein stack-top &_estack hona chahiye aur word 1 mein Reset_Handler. Jaise likha hai, hardware ek code address MSP mein load karta hai aur ek stack address par jump karta hai jaise woh code ho — instant fault.
Ek student vector_table ko .isr_vector ki jagah .data mein rakhta hai. Chip kabhi boot kyun nahi karta?
.data RAM mein rehta hai aur sirf reset handler ke dwara populate hota hai — lekin hardware vector table ko uski fixed boot location se koi bhi code run hone se pehle padhta hai, isliye reset par woh table wahan hoti hi nahi. Use boot address par Flash mein rehna chahiye.
Copy loop padhta hai while (dst < &_edata) *dst++ = *src++; lekin src ko &_sidata ki jagah &_sdata se initialize kiya gaya tha. Kya break hota hai?
Yeh Flash init image ko RAM mein copy karne ki bajay RAM ko RAM par copy karta hai, isliye .data variables mein jo bhi undefined RAM pehle se tha wahi rehta hai — Flash ki initial values kabhi use nahi hoti.
for (dst=&_sbss; dst < &_ebss; ) *dst++ = 0; ko dst < &_ebss; dst++ header mein aur *dst = 0; body mein likhne se replace kiya jaata hai. Koi bug hai?
Koi bug nahi — yeh wahi loop hai bas increment for header mein likha hai body ki jagah. Dono .bss ke har word par chalta hai aur 0 store karta hai; sirf dhyan rakho ki increment accidentally double na ho.
Koi reset vector ko seedha main par set karta hai "ek jump bachane ke liye." Kya silently break hota hai?
.data kabhi copy nahi hota aur .bss kabhi clear nahi hota, isliye initialized globals mein garbage aur zero-init globals mein random RAM rehta hai — C ke startup guarantees quietly violate ho jaate hain chahe code compile aur link ho jaaye (dekho crt0 note).
__libc_init_array() ko .data copy loop se pehle call kiya jaata hai. Yeh kyun dangerous hai?
Static/C++ constructors initialized globals ko read ya write kar sakte hain; agar .data abhi copy nahi hua, toh woh constructors garbage dekhenge. Environment setup (.data/.bss) kisi bhi constructor ke run hone se pehle complete hona chahiye.

Why questions

Hardware stack pointer ko pehle kyun load karta hai, pehle instruction fetch karne se pehle?
Kyunki Cortex-M par hardware khud registers ko stack par push karta hai jab koi exception aata hai, isliye MSP cycle zero se valid hona chahiye — warna pehla interrupt bhi memory corrupt kar dega (dekho ARM Cortex-M exception and interrupt model).
CPU ko sahi handler dhundne ki jagah vector table kyun use ki jaati hai?
Table ek O(1) indexed lookup hai — exception number n directly table[n] pick karta hai, jo fastest possible, fully-deterministic dispatch deta hai bina kisi scanning ke, jo real-time code demand karta hai.
Global variables jinhe init values chahiye, woh values Flash mein kyun rakhte hain RAM ki jagah?
RAM volatile hai aur power-up par undefined garbage hold karta hai, isliye ek value ko powered off hone ke baad survive karne ke liye woh non-volatile Flash mein hi reh sakti hai; reset handler wahi bridge hai jo us value ko Flash se uske RAM home mein laata hai.
.bss-clear missing hona classic "heisenbug" kyun hai?
Power-up par RAM contents undefined hote hain; ek board par woh 0 ho sakte hain (code kaam karta hai) aur ek identical board par garbage hote hain (code crash karta hai). Behaviour luck par depend karta hai, isliye boards aur power cycles mein aata-jaata rehta hai.
Bare-metal MCU par stack overflow usually ek clean error kyun nahi hota?
Default mein koi MMU guard page nahi hota, isliye descending stack silently .bss aur heap ko overwrite karta hai; corruption baad mein ek door, unrelated symptom ke roop mein surface hoti hai na ki immediate fault ke roop mein.
Vector table array ko const kyun declare karna chahiye?
Taaki use boot address par read-only Flash mein rakha jaaye; non-const table RAM mein land karega aur reset par jab hardware use padhega tab woh wahan hogi hi nahi — plus uske addresses kabhi change nahi hote, isliye RAM waste hoga.
Hardware registers ko early init ke dauran volatile mark karte hain lekin wahi idea .data copy loop mein kyun nahin chahiye?
volatile compiler ko bataata hai ki ek memory-mapped register program flow ke bahar change ho sakta hai, isliye reads/writes optimize nahi kiye jaane chahiye; copy loop mein ordinary RAM ke aisi koi side effects nahi hain, isliye plain pointers kaafi hain.

Edge cases

Agar .data empty ho (koi initialized globals nahi) toh kya hoga?
Tab _sdata == _edata, isliye copy loop ki condition immediately false hai aur woh zero times run karta hai — bilkul sahi, koi special case nahi chahiye.
Agar .bss empty ho toh?
_sbss == _ebss, zeroing loop zero iterations run karta hai, aur kuch clear nahi hota kyunki clear karne ke liye kuch hai hi nahi — loop gracefully degenerate ho jaata hai.
Agar _sidata (Flash source) word-aligned nahi hai lekin tum uint32_t* se copy karte ho toh kya hoga?
Ek unaligned 32-bit access core ke hisaab se fault kar sakta hai ya slow run ho sakta hai; linker normally in symbols ko 4 bytes par align karta hai, lekin agar tum alignment override karo toh byte-wise copy karna padega ya alignment fix karni padegi.
Agar reset handler ke dauran, uske handler address likhe jaane se pehle, koi peripheral interrupt fire kare, toh kya govern karta hai outcome?
Vector table mein handler address pehle se Flash mein build time par fixed hai, isliye woh valid code point karta hai chahe reset handler kitna bhi aage badha ho — danger yeh hai ki woh handler jis data ko touch karta hai (uski .data/.bss) abhi initialized nahi ho sakti, isliye setup complete hone tak interrupts typically disabled rakhe jaate hain.
Agar linker script mein RAM size chip ke actually hai usse zyada declare ki ho toh kya hoga?
_estack real memory ke baad point karta hai; pehla stack push ek non-existent address par likhta hai, bus fault ya silent loss cause karta hai — linker yeh detect nahi kar sakta, isliye script mein RAM size datasheet se match karni chahiye.
Jis exact moment par main() enter hoti hai, stack kitne bytes grow kar chuka hota hai?
Sirf branch-with-link return address (aur koi saved registers), isliye SP _estack se kuch words neeche hota hai — stack essentially empty hai, main ke locals ke liye upar se neeche descend karne ke liye ready.

Recall Self-check: teen jo tumhe bina dekhhe answer karne chahiye

Vector table ka word 0 vs word 1? ::: Word 0 = initial MSP (stack-top value); word 1 = Reset_Handler address (PC mein jaata hai). Copy-then-zero order aur kyun? ::: .data ko Flash se RAM mein copy karo, phir .bss clear karo; dono main ya kisi bhi constructor ke run hone se pehle complete hone chahiye taaki C ke global guarantees hold karein. _estack RAM ke high end par kyun hota hai? ::: Stack full-descending hai, isliye woh upar se start hota hai aur heap ki taraf neeche grow karta hai, ek well-defined collision failure mode deta hai.