__main代码分析
STM32啟動(dòng)代碼主要是分配堆棧及設(shè)置向量表,然后跳轉(zhuǎn)到__main函數(shù)。
跳轉(zhuǎn)具體到代碼段部分如下:
[cpp]?view plain?copy
當(dāng)您看到__main函數(shù)時(shí),估計(jì)應(yīng)該有不少人認(rèn)為這個(gè)是main函數(shù)的別名或是編譯之后的名字,否則在啟動(dòng)代碼中再也無(wú)法找到和main相關(guān)的字眼了。可事實(shí)是,__main和main是完全兩個(gè)不同的函數(shù),并且你無(wú)法找到__main代碼,因?yàn)檫@個(gè)是編譯器自動(dòng)創(chuàng)建的。
? ? ?查看MDK的文檔,會(huì)發(fā)現(xiàn)有這么一句說(shuō)明:It is automatically created by the linker when it sees a definition of main()。簡(jiǎn)單點(diǎn)來(lái)說(shuō),當(dāng)編譯器發(fā)現(xiàn)定義了main函數(shù),那么就會(huì)自動(dòng)創(chuàng)建__main。
?
程序經(jīng)過(guò)匯編啟動(dòng)代碼,執(zhí)行到__main()后,可以看出有兩個(gè)大的函數(shù):
__scatterload():負(fù)責(zé)把RW/RO輸出段從裝載域地址復(fù)制到運(yùn)行域地址,并完成了ZI運(yùn)行域的初始化工作。
__rt_entry():負(fù)責(zé)初始化堆棧,完成庫(kù)函數(shù)的初始化,最后自動(dòng)跳轉(zhuǎn)向main()函數(shù)。
?
分析__scatterload()函數(shù)
執(zhí)行到__main(),先跳轉(zhuǎn)到_scatterload下圖紅框框中代碼所示,執(zhí)行完后,R10和R11就被賦給成了下面兩個(gè)值。
Map文件中的symbol
然后執(zhí)行_scatterload_null代碼,將R10對(duì)應(yīng)地址存放的的4個(gè)字copy到R0~R3中,可以看出
R0:0x1000表示的是keyled.o加載域起始地址
R1:0x30000100為keyled.o運(yùn)行域地址
R2:0X160為copy的大小,keyled.o的大小從map文件中得知就是0x160 Byte
R3:0X1E4 是_scatterload_copy 代碼的起始地址,實(shí)用BXR3 就能跳轉(zhuǎn)到_scatterload_copy來(lái)復(fù)制代碼。
?
跳到_scatterload_copy,開始copy,循環(huán)0x16次,每次搬移4個(gè)字(16Byte),共搬移0x16*0x10=0x160
復(fù)制完keyled.o代碼后,進(jìn)一步循環(huán)到_scatterload_null準(zhǔn)備好,ZI段需要清零的地址和范圍
執(zhí)行完這個(gè)循環(huán)后
R1:0x30050000 為ZI段的起始地址
R2:0x618為ZI段大小,換成十進(jìn)制是1560.從map文件得知ZI大小就是1560Byte
R3:0x20c 為_scatterload_zeroinit 的地址
執(zhí)行下面紅框框中循環(huán)體,共清零0x610Byte范圍,然后再執(zhí)行藍(lán)框框中代碼,清零8Byte,總共0x618
ZI段清零(0x30050000~0x30050618)
然后使用BX R14跳轉(zhuǎn)到0x000001BC處,順序執(zhí)行到BL? __rt_enty 指令
成功跳轉(zhuǎn)到__rt_enty函數(shù)
?
分析__rt_entry()函數(shù)
先調(diào)用__user_setup_stackheap()函數(shù)來(lái)建立堆棧
可以看出在這個(gè)函數(shù)中,會(huì)執(zhí)行到BL__user_initial_stackheap()函數(shù),這樣也就明白了,為什么使用分散加載文件,需要設(shè)置__user_initial_stackheap這個(gè)函數(shù)來(lái)設(shè)置堆棧空間。
總結(jié)
以上是生活随笔為你收集整理的__main代码分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: uboot之fastboot烧录镜像
- 下一篇: 马云:未来10年,人类将面临AI、IoT