5.5.16 · D1 · Coding › Embedded Systems & Real-Time Software › Startup code — vector table, reset handler, stack initializa
Naya power-on CPU aapke C program ke baare mein kuch nahi jaanta — woh sirf ek number padhta hai stack ke liye, phir ek address padhta hai aur wahan jump karta hai. Startup code woh chota sa code hai jo us address par baitha hai jiska ek hi kaam hai — woh duniya banana jisko aapka C program assume karta hai ki pehle se exist karti hai: ek working stack, globals apni sahi values ke saath, aur baaki sab kuch zero set karke.
Parent note padhne se pehle, aapko uski vocabulary chahiye. Yeh page har term aur notation ko bilkul zero se build karta hai — CPUs, memory, compilers ya linkers ki koi prior knowledge assume nahi ki gayi. Upar se neeche padho; har block uske upar wale par lean karta hai. Do words jo aapko jaldi milenge — reset handler aur linker — yahan ek line ka preview milega aur baad mein full definition:
Definition Do words jo aapko unke full section se pehle dikhenge
Reset handler : aapka code ka sabse pehla piece jo power-on ke baad run hota hai. Iska kaam C environment banana hai (memory copy aur zero karna) aur phir main() call karna. Full treatment tab aayegi jab aapke paas vocabulary ho — abhi ke liye bas "boot code jo hum likh rahe hain" padhein.
Linker : woh tool jo compiling ke baad decide karta hai kaunsa address har function aur variable ko milega aur pieces ko ek program image mein stitch karta hai. §7 mein properly define hoga.
Definition Memory aur addresses
Computer ki saari storage ko ek lambi shelf of tiny boxes samjho, har ek mein ek byte (0 se 255 tak ka number) hota hai. Har box par ek permanent number stamped hota hai — uska address . "Address 0x20000000" ka matlab sirf yeh hai "woh box jiska number 0x20000000 hai".
0x prefix ka matlab hai number hexadecimal (base-16) mein likha hai — bade addresses likhne ka ek compact tarika. 0x10 sixteen hai, 0xFF 255 hai. Engineers hex use karte hain kyunki memory addresses isme tidy lagte hain.
Definition Numbers mein underscore bas ek comma hai
Lambe hex addresses padhne mein mushkil hote hain, isliye hum aksar 0x2000_5000 likhte hain 0x20005000 ki jagah. ==Underscore _== number ke andar ek digit separator hai — sirf sजावट ke liye digits group karne ke liye, bilkul 1,000,000 mein comma ki tarah. Value par koi asar nahi hota; 0x2000_5000 aur 0x20005000 ek hi number hain. C khud bhi yeh grouping allow karta hai.
Definition Word = 4 bytes = 32 bits
In chips par ek word 4 bytes = 32 bits hota hai — woh natural chunk jo CPU ek baar mein read aur write karta hai. Kyunki ek word 4 boxes span karta hai, whole words 0x00, 0x04, 0x08, 0x0C, ... addresses par baithte hain (4 se jump karte hue). Yahan har important number — ek address, stack-top, ek initial value — exactly ek word mein fit hota hai.
Figure s01 neeche yeh wall draw karta hai: paanch boxes ek row mein, har ek apne address 0x00, 0x04, 0x08, … ke saath label hua. Red note yaad dilata hai ki addresses 4 se jump karte hain kyunki ek word 4 boxes span karta hai. Yeh picture dimag mein rakho: baad ka har step "us box par jao, word padho ya likho" hai.
Intuition Numbered boxes yahan kyun matter karte hain
Poori startup story hai "CPU box #0 padhta hai, phir box #4, phir ek region se doosre mein boxes copy karta hai." Agar aap memory ko yeh numbered wall samjho, toh baad ka har step sirf "us box par jao, word read/write karo" hai.
Related layout ideas Stack vs Heap memory layout mein hain.
Ek value aligned hoti hai jab uska address uske size ka multiple ho: ek 4-byte word ko ek aise address par start karna chahiye jo 4 se divisible ho (0x00, 0x04, 0x08, …), kabhi 0x03 par nahi. Cortex-M hardware require karta hai ki word accesses aligned hon — ek misaligned word read fault kar sakta hai. Isliye har table slot aur har stack push 4 ke steps mein chalti hai, aur initial SP 4 ka multiple hona chahiye (actually ABI ke liye 8). Alignment koi style choice nahi hai; yahi reads ko legal rakhta hai.
Definition Byte order (endianness)
Ek 32-bit number chaar boxes span karta hai, toh lowest-addressed box mein kaunsa byte jaata hai? Cortex-M little-endian hai: least-significant byte sabse low address par hota hai. Toh number 0x2000_5000 jo 0x00 par stored hai woh 0x00 in box 0x00, 0x50 in box 0x01, 0x00 in box 0x02, 0x20 in box 0x03 rakhega.
Yeh kyun jaanna zaroori hai: jab reset handler .data ko word by word (4 bytes at a time) copy karta hai, byte order kabhi matter nahi karta — poora word intact move hota hai. Lekin agar aap kabhi debugger mein memory byte by byte inspect karo, toh 42 (0x0000002A) 2A 00 00 00 dikhega, jo "ulta" lagta hai. Woh surprise endianness hai, bug nahi.
Flash : woh memory jo power off hone par bhi yaad rakhti hai . Aapke program ki machine code aur variables ki initial values yahan burn hoti hain. Runtime par yeh read-only hai (likhna slow/awkward hai).
RAM : woh memory jo fast hai lekin bhulakkar — power-up par iske contents garbage/undefined hote hain aur power cut hone par gayab ho jaate hain. Runtime par change hone wale variables yahan rehte hain.
Figure s02 unhe do boxes ke roop mein contrast karta hai: Flash (black) mein aapka code aur init value 42 hai; RAM (black) woh jagah hai jahan variable g runtime par actually rehta hai lekin garbage se start karta hai. Unke beech ka red arrow is poore page ka sabse important action hai — Flash se RAM mein 42 ki copy . Reset handler jo kuch karta hai woh uss ek red arrow aur ek wipe mein capture hota hai.
Intuition Split kyun kaam create karta hai
int g = 42; jaisi line ko chahiye ki g RAM mein rahe (taaki change ho sake) lekin uski starting value 42 sirf Flash mein survive power-off kar sakti hai. Toh number 42 Flash mein baithta hai aur kuch main() run hone se pehle use RAM mein copy karna padta hai. Woh "kuch" reset handler hai (upar preview hua — boot code jo hum likh rahe hain). Yahi copy startup code exist karne ki wajah hai.
Definition CPU aur Program Counter (PC)
CPU woh worker hai jo instructions padhta hai aur unhe karta hai. Woh ek special number rakhta hai, Program Counter (PC) : next instruction ka address jo run karna hai. Har step: PC par instruction padho, karo, PC advance karo. "Jumping" ka matlab PC mein ek naya address likhna hai.
PC ek ungli hai jo boxes ki wall par point kar rahi hai , instructions run hone ke saath seedhi slide karti hai. Reset par chip designers physically ungli ko ek fixed starting spot par wire karte hain — yahi "CPU ek hardware-defined address se executing shuru karta hai" ka poora matlab hai.
Cortex-M machine model par zyada: ARM Cortex-M exception and interrupt model .
Definition Stack aur Stack Pointer
Stack RAM ka ek scratch region hai jise plates ke stack ki tarah use kiya jaata hai: jab koi function call hota hai, uska return address aur local variables push kiye jaate hain upar; jab finish hota hai, woh pop ho jaate hain. Stack Pointer (SP) ek number hai jo current top plate ka address rakhta hai. Cortex-M par main wala MSP (Main Stack Pointer) kehlaata hai.
Figure s03 memory ko vertically khada karta hai. Top marker _estack hai; uske neeche do pushed items hain (ek return address aur ek local variable). Left par red arrow SP hai, hamesha last written item ki taraf point karta hua; right par red arrow growth direction dikhata hai — neeche ki taraf , kyunki har push pehle 4 subtract karta hai, phir likhta hai. Figure ko top-to-bottom padhein — "high addresses upar, stack neeche low addresses ki taraf eat karta hua."
Definition Full-descending stack
Cortex-M par stack full-descending hai: SP last written item par point karta hai, aur ek push pehle SP se 4 subtract karta hai, phir likhta hai . Toh stack downward grow karta hai (smaller addresses ki taraf). Isliye starting SP top address par set hota hai aur pehla push uske just neeche land karta hai. Note karo ki pushes 4 ke steps mein chalte hain (ya ABI ke liye 8), isliye ek properly-aligned initial SP hamesha aligned rehta hai — §1 mein alignment definition dekho.
Intuition SP kisi bhi function se pehle kyun exist karna chahiye
Ek function apna return address aur locals save karne ke liye jagah ke bina run nahi kar sakta . Koi valid SP nahi → pehla function call hi ek random box mein scribble kar deta hai → crash. Isliye hardware SP ko reset par sabse pehle load karta hai, kisi bhi code ko touch karne se pehle.
Heap ke saath compare karo Stack vs Heap memory layout mein.
Ek pointer bas ek variable hai jiska value ek address hai — ek number jo bolta hai "woh cheez us box mein hai." C mein, &x ka matlab hai "x ka address", aur *p ka matlab hai "us box mein value jo p point karta hai."
Definition Function pointer
Ek function pointer ek pointer hai jiska target box kisi function ki pehli instruction rakhta hai. Iska C type void (*)(void) likha jaata hai — padhein "ek function ka address jo kuch nahi leta aur kuch nahi return karta." Is address ko PC mein daalna = us function ko call karna.
Intuition Vector table ko yeh kyun chahiye
Vector table (Section 8) jump karne ke addresses ki list hai. Code-ka-address exactly ek function pointer hai, toh poori table naturally function pointers ka array hai — except slot 0, jo same-shaped slot mein cleverly ek stack address store karta hai.
*dst++ = *src++ pointers ko move karta hai, data ko nahi."
Kyun sahi lagta hai: aap ++ dekhte ho aur sochte ho arrow move hoti hai. Fix: yeh dono kaam karta hai, order mein — pehle *src ko *dst mein copy karo (data), phir dono pointers ko next box par bump karo. Yeh .data copy loop ka compact core hai.
Figure s04 sections ko line up karta hai aur har ek ko woh action label karta hai jo boot code karta hai: .text aur .rodata (kuch nahi — pehle se Flash mein hain, directly padhe jaate hain), .data red mein (COPY Flash→RAM), aur .bss (WIPE to 0). .data par red highlight woh ek section mark karta hai jise Figure s02 ki copy chahiye. Figure padhna mental sorting rule sikhata hai: "startup par mujhpar kya hona chahiye?"
Intuition Ek ki jagah kai piles kyun
Har pile ko startup par alag treatment chahiye: .text aur .rodata ko kuch nahi chahiye (pehle se Flash mein hain, jagah par hi padhte hain), .data ko copy chahiye, .bss ko wipe chahiye. Variables ko "boot par mujhpar kya hona chahiye" ke hisaab se sort karna exactly isliye yeh names exist karte hain.
Full detail: Linker scripts and memory sections (.text .data .bss) .
Definition Linker aur linker symbols
Linker woh tool hai jo compiler ke baad run hota hai: yeh decide karta hai kaunsi address par har cheez rehti hai aur saare compiled pieces ko ek program image mein glue karta hai. Jaise yeh memory lay out karta hai, woh named markers bhi drop kar sakta hai jinhein linker symbols kehte hain — woh names jo addresses (regions ke beech boundaries) represent karte hain. Startup code ko yeh markers diye jaate hain:
_sdata, _edata — RAM mein .data ka s tart / e nd.
_sbss, _ebss — RAM mein .bss ka start / end.
_sidata — Flash address jahan .data ki initial values stored hain ("i nit data " image).
_estack — stack ka top. Linker script ise RAM ke end ke theek baad first invalid byte par set karta hai, word/stack alignment ke hisaab se rounded — yaani highest usable byte ke ek aage, taaki pehla push ek valid, aligned address par RAM ke andar land kare.
Intuition Hardcoded numbers ki jagah symbols kyun
Aap coding time par nahi jaante ki .data kitna bada hoga — yeh depend karta hai ki aapne kitne globals declare kiye hain. Toh startup loop kehta hai "_sdata se _edata tak copy karo," linker ko real numbers memory lay out karne ke baad fill in karne deta hai. Loop bounds computed hain, kabhi guess nahi kiye jaate.
_sdata ek variable hai jo data rakhta hai."
Kyun sahi lagta hai: yeh extern uint32_t _sdata; declare hua hai. Fix: hum sirf iska address use karte hain (&_sdata). Symbol ka address boundary hai; uski "value" meaningless hai. Isliye startup code &_sdata, &_edata, etc. likhta hai.
Details Linker scripts and memory sections (.text .data .bss) aur The C runtime and crt0 mein.
Ek vector table addresses ka array hai jo hardware padhta hai jaanne ke liye ki kahan jaana hai. Cortex-M par yeh ek fixed spot par baithta hai (ya jahan VTOR register point karta hai). Iske pehle kuch slots aisa dikhte hain:
Offset
Contents
0x00
initial SP value (stack ka top, _estack)
0x04
reset handler ka address (entry point)
0x08
NMI handler address
0x0C
HardFault handler address
0x40+
peripheral interrupt handler addresses
Yahi woh table hai jo Figure s01 ki wall preview kar rahi thi — har slot ek word hai, toh offsets 0x00, 0x04, 0x08, 0x0C, … chalta hai, exactly woh 4-step jumping jo aapne wahan dekha.
Ab aapke paas use padhne ke liye har piece hai:
Yeh ek array hai (Section 1: numbered boxes ek row mein, 4-byte aligned).
Iske entries addresses of code hain = function pointers (Section 5).
Except entry 0, jo stack-top address _estack hai (Section 4 & 7).
Is table ko relocate karna Bootloaders and VTOR relocation mein hai. VTOR jaise registers Volatile, memory-mapped registers and hardware init ke through touch kiye jaate hain.
Hardware control knobs address wall mein special boxes ke roop mein appear hote hain (memory-mapped registers ). volatile compiler ko bolta hai "yeh box apne aap change ho sakta hai — iske reads/writes kabhi optimize mat karo." Startup code jo hardware (clocks, VTOR) touch karta hai use chahiye. Dekho Volatile, memory-mapped registers and hardware init .
Yeh diagram kaise padhein: har box upar ke sections se ek foundation hai; ek arrow "A → B" ka matlab hai "B samajhne ke liye A chahiye." Upar se koi bhi path follow karo aur aap exactly woh order walk kar rahe ho jo yeh page sikhata hai. Har path eventually "Startup code topic" box mein feed hota hai neeche — woh parent note hai jiske liye aap prepare kar rahe ho. Do beech ke merge-points (reset handler ka copy/zero kaam, aur vector table) woh jagah hain jahan kai foundations aek saath aate hain, toh yeh woh ideas hain jo zyada over-learning ke laayak hain.
Pointers and function pointers
Sections text rodata data bss
Vector table as address array
Reset handler copies and zeros
Khud test karo — parent note kholne se pehle har ek obvious feel hona chahiye.
An address is memory mein ek box (byte) par stamped permanent number.
0x in front of a number meansnumber hexadecimal (base-16) mein likha gaya hai.
The underscore inside a number like 0x2000_5000 means value ke baare mein kuch nahi — yeh bas readability ke liye ek digit separator hai, jaise comma.
A word on Cortex-M is 4 bytes (32 bits), toh words 4 apart addresses par baithte hain.
"Aligned" means address value ke size ka multiple hai; ek word 4 ke multiple par start hona chahiye, nahi toh access fault kar sakta hai.
Little-endian means ek multi-byte value ka least-significant byte lowest address par stored hota hai.
Flash keeps its contents when power off ho; RAM ke contents power-up par undefined hote hain.
The Program Counter (PC) holds next instruction ka address; jumping = isme naya address likhna.
The Stack Pointer (SP/MSP) holds stack ke current top ka address.
"Full-descending" means SP last used item par point karta hai, aur push pehle 4 subtract karta hai, phir likhta hai — stack downward grow karta hai.
A function pointer is ek variable jo function ki pehli instruction ka address rakhta hai; type void (*)(void).
The reset handler is aapke code ka pehla piece jo power-on ke baad run hota hai; .data copy karta hai, .bss zero karta hai, phir main call karta hai.
The linker is woh tool jo har function aur variable ko address assign karta hai aur program glue karta hai, boundary symbols drop karte hue.
.rodata holdsread-only constants jaise string literals; yeh Flash mein rehte hain aur directly padhe jaate hain, koi copy ya zero nahi chahiye.
.data holdsnon-zero initial values wale globals, startup par Flash se RAM mein copy kiye jaate hain.
.bss holdszero-initialized globals, startup par 0 se wipe kiye jaate hain (Flash mein stored nahi).
_estack isstack ka top — RAM ke end ke baad first invalid byte (alignment ke hisaab se rounded), reset par MSP mein load hota hai.
_sidata isFlash address jahan .data ki initial values stored hain, RAM mein copy karne ke liye.
We use &_sdata (its address) not _sdata because linker symbols ka meaning sirf unke address mein hai, ek region boundary mark karte hue.
*dst++ = *src++ doessrc jo point karta hai uski value dst jo point karta hai wahan copy karo, phir dono pointers advance karo.